Issue #11882 has been updated by Robert A. Heiler.


I concur with Hampton Catlin for the most part (save for the
name "Map", that is not a good name IMO).

I assume that exposing Symbols was never directly the primary
design goal to be had; it came to be, and please feel free to
correct  me if I am incorrect, mostly because using Symbols would be
faster than Strings and I assume that especially rails had pushed
for it due to having found other problems lateron with their big
code base. (The rails users also originated HashWithIndifferentAccess
as far as I am aware, but that is an abomination to type. I would
never use such a long name, but I mentioned it because it also
taps into the question of "strings versus symbols" situation,
so this is a recurring theme.)

I do not have any particular route to recommend or partake in,
so I can't pick from the above selection nor can I really add
any myself, but I would like to say that I concur with Hampton
Catlin even if I am coming from a somewhat different angle.

To me, as a newbie (I still am a newbie really even after years,
but I am like a somewhat "competent" newbie by now), I don't really
want to have to think about whether I need to use Strings or
Symbols at all as identifiers. Don't get me wrong there, I actually
love Symbols for a completely odd reason - I can use :foo rather
than 'foo' so I can save one character! (I could also use ?foo 
but I find ? ugly and we have method names with ? and also 
ternary, I don't want to use so many ?; thankfully we have the
lonely-person-stares-at-dot operator rather than another ?
again)

But, from a conceptual point of view, when I am writing some
ruby scripts, having to wonder or ponder about whether to use
Symbols or Strings, I feel it adds a small layer of complexity
that should not really exist in the first place (from the
"human user perspective" that is; it's fine as an internal 
part of ruby).

The name "Map" is a bit weird though. Reason I dislike that
name is because we already have .map and my brain refers 
to .map in a completely different way (aka, "apply on each
element" mostly). And if I were to see Map.map I would want
to not like it.

> I guess I just see 95% of Hash usage being made up of instances
> where symbols and strings are treated equally, and compensating
> code is required at every step to ensure that. I find it odd
> that this is considered an edge-case.

Oh I know how you feel there. :)

I remember that in my cookbooks project, I am saving every program
as a yaml file, so all programs will be described via yaml. So
this is a "yaml database", ok flat files.

Then, when I wanted to access the giant hash that is created
by loading all yaml files, I had to wonder whether I want to
keep them saved as a string or as a symbol (the key identifiers,
e. g. "vim" versus :vim to access all information pertaining
to vim).

I do not remember which way I went offhand but whatever it was,
I decided that I will convert input to the target format anyway
(so either I am doing a .to_s or a .to_sym but it's an extra
step of thinking required that really does not help me a lot;
on the other hand, it also isn't something that is a huge
issue to me either, it's more a peculiarity).

Ruby 3.0 is in the pipeline!

----------------------------------------
Feature #11882: Map or NamedMap
https://bugs.ruby-lang.org/issues/11882#change-55802

* 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/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>