How to create Hash with string keys by default

21,704

Solution 1

Use hash rocket syntax:

h = { "a" => 123 }
#=> {"a"=>123}
h['a']
#=> 123

Solution 2

Use hashrocket instead of colon :

h = { "a" => 123 }
#=> {"a"=>123}

Solution 3

Try

h = { "a" => 123 }

Colon make your key a symbol.

Solution 4

To clear a misunderstanding:

it's confusing/frustrating when the string key gets modified to a symbol

It wasn't a string to begin with. This is just another syntax for creating symbol keys. Consider:

:'foo-bar'.class # => Symbol

The idea is that sometimes, there can be characters in the symbol that look like something completely different.

For example, the above without quotes would mean "create the literal symbol :foo and from it, subtract the value of the local variable/method invocation result bar". Previously, there was no way to construct such symbols, other than to use String#to_sym. And you have to agree this looks terrible:

{'foo-bar'.to_sym => 42, :this_now_needs_rocket_notation => 'baz'}

Quotes in general don't mean string creation, they mean take as is and/or define boundaries for something. Therefore, they incidentally make a lot of sense for literal string syntax, but this is not their only application.

Share:
21,704
Joerg
Author by

Joerg

Updated on December 04, 2020

Comments

  • Joerg
    Joerg over 3 years

    When I do the following:

    h = { "a": 123 }
    

    Ruby converts the key to a symbol automatically.

    h[:a]  # => 123
    h["a"] # => nil
    

    How can I prevent this behaviour? I created the hash with a string key, and would like to keep it that way without always having to call Hash#stringify_keys.

  • Joerg
    Joerg over 7 years
    Pity ... such an ugly notation ... :(
  • Andrey Deineko
    Andrey Deineko over 7 years
    @Joerg it is how it was before new hash notation appeared.
  • Joerg
    Joerg over 7 years
    Yeah I know ... but since the new notation - there's no going back :)
  • Andrey Deineko
    Andrey Deineko over 7 years
    @Joerg what if you wanted to have some object as a key? { Object.new => :hello } - there is no way to write it in the new form, so. New syntax works only for symbol keys, everything else needs to go old way.
  • Joerg
    Joerg over 7 years
    True ... Still, when using a colon I guess it's confusing/frustrating when the string key gets modified to a symbol - been catching me out a lot. Anyway thanks.
  • Sergio Tulentsev
    Sergio Tulentsev over 7 years
    Hashrocket isn't going anywhere. Also, it's looks pretty cool :)
  • Sergio Tulentsev
    Sergio Tulentsev over 7 years
    @Joerg: wanna see ugly syntax? Here's one: {:"user.name" => "Bill"} I snapped my teeth every time I saw one of those. :) But then it became possible to write {"user.name": "Bill"}. Doesn't look as bad now, does it? :)
  • Stefan
    Stefan over 7 years
    @SergioTulentsev that should be { user: { name: 'Bill' } } ;-)
  • Sergio Tulentsev
    Sergio Tulentsev over 7 years
    @Stefan: that's not activerecord :)
  • Aleksei Matiushkin
    Aleksei Matiushkin over 7 years
    @SergioTulentsev BTW, using a proper font with ligatures (like Hasklig) makes hashrockets look really cool.
  • Sergio Tulentsev
    Sergio Tulentsev over 7 years
    @mudasobwa: oohhh, nice!
  • Sergio Tulentsev
    Sergio Tulentsev over 7 years
    @mudasobwa: gonna give it a try :)
  • Stefan
    Stefan over 7 years
    @mudasobwa monospaced ligatures, that's genius!
  • Stefan
    Stefan over 7 years
    @mudasobwa although I see an ugly issue with !=