48

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.

9
  • 3
    key: value is just a shortcut for :key => value, so there is actually no string key in your example – "a": 123 becomes :"a" => 123 (note the leading :) Commented Oct 21, 2016 at 9:19
  • Could be nice maybe if { "a": 123 } uses an HashWithIndifferentAccess under the hood, as opposed to a Hash then. Commented Oct 21, 2016 at 9:22
  • @Joerg: you're welcome to submit a feature request :) Commented Oct 21, 2016 at 9:24
  • @SergioTulentsev please quit giving advices like that. HashWithIndifferentAccess has nothing to do with ruby :) Commented Oct 21, 2016 at 9:31
  • @mudasobwa: You know I know :) Commented Oct 21, 2016 at 9:32

4 Answers 4

66

Use hash rocket syntax:

h = { "a" => 123 }
#=> {"a"=>123}
h['a']
#=> 123
Sign up to request clarification or add additional context in comments.

13 Comments

@Joerg it is how it was before new hash notation appeared.
Yeah I know ... but since the new notation - there's no going back :)
@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.
Hashrocket isn't going anywhere. Also, it's looks pretty cool :)
@SergioTulentsev BTW, using a proper font with ligatures (like Hasklig) makes hashrockets look really cool.
|
16

Use hashrocket => instead of colon :

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

You can access the value now using

h["a"]
#=> 123

On a side note, if you're using rails and want to ensure the values are accessed with both symbol and string keys

You can make use of Hash#with_indifferent_access

h = { a: 123 }.with_indifferent_access
#=> {"a"=>123}

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

1 Comment

This is the actual answer. It's pragmatic and useful. The others are interesting to dive into the underpinnings of how Ruby works and read the discussions but this gets you going immediately, with a suggestion for those using Rails as well. Nice job.
6

Try

h = { "a" => 123 }

Colon make your key a symbol.

1 Comment

Pity ... such an ugly notation ... :(
5

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.