From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: poffice@blade.nagaokaut.ac.jp Delivered-To: poffice@blade.nagaokaut.ac.jp Received: from kankan.nagaokaut.ac.jp (smtp.nagaokaut.ac.jp [133.44.2.24]) by blade.nagaokaut.ac.jp (Postfix) with ESMTP id 96C5F19E003D for ; Tue, 29 Dec 2015 02:43:41 +0900 (JST) Received: from voscc.nagaokaut.ac.jp (voscc.nagaokaut.ac.jp [133.44.1.100]) by kankan.nagaokaut.ac.jp (Postfix) with ESMTP id 5EF89B5D8CB for ; Tue, 29 Dec 2015 03:16:18 +0900 (JST) Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by voscc.nagaokaut.ac.jp (Postfix) with ESMTP id 5D28818CC7E2 for ; Tue, 29 Dec 2015 03:16:18 +0900 (JST) Received: from [221.186.184.76] (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id D8809120504; Tue, 29 Dec 2015 03:16:16 +0900 (JST) X-Original-To: ruby-core@ruby-lang.org Delivered-To: ruby-core@ruby-lang.org Received: from o10.shared.sendgrid.net (o10.shared.sendgrid.net [173.193.132.135]) by neon.ruby-lang.org (Postfix) with ESMTPS id 4AE761204CE for ; Tue, 29 Dec 2015 03:16:14 +0900 (JST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sendgrid.me; h=from:to:references:subject:mime-version:content-type:content-transfer-encoding:list-id; s=smtpapi; bh=olrE5to0yBJesimG0nZiuXl9mug=; b=ryFJXo+JjeaNKB5Pnz +RVnFjFqymKQalmX+IkZ+nJ/ue+wzjVa+AMN9npHY8NBZt0koNaxHwXKiv52W9qx wha4+bBIEWLYKSUNkNWQ2qJgW4JDFif0NGz7K51q1pEJxywJm6mU0LVQssyq5yf3 Hy2grvUY+EqMHLSeT95sw+YkQ= Received: by filter0501p1mdw1.sendgrid.net with SMTP id filter0501p1mdw1.19149.56817C6316 2015-12-28 18:16:03.304982608 +0000 UTC Received: from herokuapp.com (ec2-54-159-221-212.compute-1.amazonaws.com [54.159.221.212]) by ismtpd0006p1iad1.sendgrid.net (SG) with ESMTP id 421rX4leTmuZCiUkT--T6A Mon, 28 Dec 2015 18:16:03.681 +0000 (UTC) Date: Mon, 28 Dec 2015 18:16:03 +0000 From: rr.rosas@gmail.com To: ruby-core@ruby-lang.org Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 47161 X-Redmine-Project: ruby-trunk X-Redmine-Issue-Id: 11882 X-Redmine-Issue-Author: hcatlin X-Redmine-Issue-Assignee: matz X-Redmine-Sender: rosenfeld X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: All Auto-Submitted: auto-generated X-SG-EID: ync6xU2WACa70kv/Ymy4QrNMhiuLXJG8OTL2vJD1yS74Cp82/wJ4V06W7HY19FfoXp8W6P4RQFNhwb 4M1B3oiGiGv4z7dr+mOxB7s2VyGY+ej0OhSuBqOSw1aTQyfGFU/zigRDwMEOQrI3o/tKrWd4vXB6fP ushbOoQgUvrjO26G1oeMCeLZUrHIuCjRcEUe36bYM+kGD17oyVIGEGA2sg== X-ML-Name: ruby-core X-Mail-Count: 72561 Subject: [ruby-core:72561] [Ruby trunk - Feature #11882] Map or NamedMap X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" Issue #11882 has been updated by Rodrigo Rosenfeld Rosas. For a long time I've been saying Symbols are the biggest disadvantage of Ruby, so you can count on me with any efforts in trying to make symbols and strings interchangeable even if only for hashes. I've tried many suggestions, like making the symbols syntax generate frozen strings, or making their comparison work string-wise and even tried to make Hash work the way you described without the need to create new classes for that. I've also wanted that the short-style syntax for hashes used strings as keys instead of symbols. This symbol vs string thing is a source of lots of bugs and takes us a long time to search for other use cases to understand whether we should use symbols or strings as keys while we only care about the name of the keys... If it's not possible to make this transparent out of the box, at least I'd like Ruby to support some short syntax for them, like {}i (i as a shortcut to indifferent here), but it means we wouldn't be able to call methods like this: do_something at: Date.today + 1 Even worse, if 'at' is a named argument, than if a hash is passed to do_something, then the keys have to be symbols (and the argument must be a Hash). As I said before, I'd prefer a more general and transparent option even if it's not backwards-compatible (although very unlikely to introduce real problems) and cleaner than something like what has been proposed here. But I still prefer a solution like this than having to worry about the symbols vs strings dilema when I only care about named identifiers. ---------------------------------------- Feature #11882: Map or NamedMap https://bugs.ruby-lang.org/issues/11882#change-55819 * Author: Hampton Catlin * Status: Open * Priority: Normal * Assignee: Yukihiro Matsumoto ---------------------------------------- Hash is one of the best features of Ruby. I remember being so pleased when I first learned Ruby to find out that *anything* could be a key and that you could do some really clever things with scripts, if you key of non-traditional elements. However, like many people, 10 years into using Ruby, I still am writing code to cast around symbols to strings and strings to symbols, just to use Hash as a more traditional dictionary, keyed with string-like values. And, explaining to a junior programmers why they broke the code by using a key of a different type... it's not the most elegant thing to have to explain over and over. Several proposals exist for how to deal with this, and all have been rejected... however it doesn't seem like it's for essential reasons, more technical or syntactic issues. Coming up with syntax is something I quite enjoy (Sass/Haml), so I thought I'd make a pitch for it. Requirements: 1) Doesn't break existing code 2) Doesn't totally destroy the parser 3) Seems simple to differentiate 4) Clear upgrade path My proposal is to introduce an entirely different type of Hash, called a Map (or NamedMap, if that's too ambiguous), that requires a string-like key. There are no other types of keys allowed on this Hash, other than either strings or symbols. Internally, each key would be considered a symbol only. ~~~ map = Map.new(a: 2, b: 3) map["a"] #=> 2 map[:a] #=> 2 ~~~ Already, we're better than HashWithIndifferentAccess, as it's clearly a bit easier to type. ;) What about a literal syntax? ~~~ map = {{a: 2}} empty_map = {{}} ~~~ As far as I can tell in the Ruby-syntax style, this should be pretty easy to distinguish syntactically from both a regular hash literal and a block. Further, as almost every method's option hash is string-keyed, you could easily define this. ~~~ def my _method(arg1, options = {{}}) end ~~~ Immediately, you could deal with your options hash, and not have to stress about if the end user has passed in strings or symbols into the options. It would be trivial to create a Map polyfill for most libraries to start using the non-literal version right away, as it would basically be HashWithIndifferentAccess, except we need to guarantee that the keys are string-like. So, to sum up, we avoid the 'breaking other people's existing code' by introducing a new data-type, the literal syntax (I think) should be fairly easy to implement, and it makes a very natural keyed data object (e.g. Javascript Objects) and brings that to Ruby. -- https://bugs.ruby-lang.org/