Is there any difference between the `:key => "value"` and `key: "value"` hash notations?

28,615

Solution 1

Yes, there is a difference. These are legal:

h = { :$in => array }
h = { :'a.b' => 'c' }
h[:s] = 42

but these are not:

h = { $in: array }
h = { 'a.b': 'c' } # but this is okay in Ruby2.2+
h[s:] = 42

You can also use anything as a key with => so you can do this:

h = { C.new => 11 }
h = { 23 => 'pancakes house?' }

but you can't do this:

h = { C.new: 11 }
h = { 23: 'pancakes house?' }

The JavaScript style (key: value) is only useful if all of your Hash keys are "simple" symbols (more or less something that matches /\A[a-z_]\w*\z/i, AFAIK the parser uses its label pattern for these keys).

The :$in style symbols show up a fair bit when using MongoDB so you'll end up mixing Hash styles if you use MongoDB. And, if you ever work with specific keys of Hashes (h[:k]) rather than just whole hashes (h = { ... }), you'll still have to use the colon-first style for symbols; you'll also have to use the leading-colon style for symbols that you use outside of Hashes. I prefer to be consistent so I don't bother with the JavaScript style at all.

Some of the problems with the JavaScript-style have been fixed in Ruby 2.2. You can now use quotes if you have symbols that aren't valid labels, for example:

h = { 'where is': 'pancakes house?', '$set': { a: 11 } }

But you still need the hashrocket if your keys are not symbols.

Solution 2

key: "value" is a convenience feature of Ruby 1.9; so long as you know your environment will support it, I see no reason not to use it. It's just much easier to type a colon than a rocket, and I think it looks much cleaner. As for there being a gem to do the conversion, probably not, but it seems like an ideal learning experience for you, if you don't already know file manipulation and regular expressions.

Solution 3

Ruby hash-keys assigned by hash-rockets can facilitate strings for key-value pairs (e.g. 's' => x) whereas key assignment via symbols (e.g. key: "value" or :key => "value") cannot be assigned with strings. Although hash-rockets provide freedom and functionality for hash-tables, specifically allowing strings as keys, application performance may be slower than if the hash-tables were to be constructed with symbols as hash-keys. The following resources may be able to clarify any differences between hashrockets and symbols:

Solution 4

The key: value JSON-style assignments are a part of the new Ruby 1.9 hash syntax, so bear in mind that this syntax will not work with older versions of Ruby. Also, the keys are going to be symbols. If you can live with those two constraints, new hashes work just like the old hashes; there's no reason (other than style, perhaps) to convert them.

Solution 5

Doing :key => value is the same as doing key: value, and is really just a convenience. I haven't seen other languages that use the =>, but others like Javascript use the key: value in their Hash-equivalent datatypes.

As for a gem to convert the way you wrote out your hashes, I would just stick with the way you are doing it for your current project.

*Note that in using key: value the key will be a symbol, and to access the value stored at that key in a foo hash would still be foo[:key].

Share:
28,615
AdamNYC
Author by

AdamNYC

Updated on July 08, 2022

Comments

  • AdamNYC
    AdamNYC almost 2 years

    Is there any difference between :key => "value" (hashrocket) and key: "value" (Ruby 1.9) notations?

    If not, then I would like to use key: "value" notation. Is there a gem that helps me to convert from :x => to x: notations?

  • mu is too short
    mu is too short over 9 years
    PS: It is not JSON-style, it is JavaScript-style. JSON requires keys to be quoted.
  • B Seven
    B Seven about 9 years
    h = { 'a.b': 'c' } is now legal as of Ruby 2.2.0. See bugs.ruby-lang.org/issues/4276
  • mu is too short
    mu is too short about 9 years
    @BSeven: Thanks, I updated my other big hashrocket answer awhile ago but missed this one.
  • Nic Nilov
    Nic Nilov almost 9 years
    Why do you feel the h[:s] = 42 example relates to this question? In my opinion, JavaScript style vs hashrocket style is only relevant to hash key/value pair definition, and not to addressing hash elements by keys. Therefore the h[s:] = 42 example seems to be misleading.
  • mu is too short
    mu is too short almost 9 years
    @NicNilov That's relevant because the JavaScript style is about symbols as Hash keys and the notations allowed are, confusingly, context dependent.
  • Nic Nilov
    Nic Nilov almost 9 years
    Cannot agree. When addressing a hash slot by symbol you always use h[:s] = 42 notation. There is no other option. It's when you define key/value pairs you got options of { key: value } JavaScript style or { :key => value } hashrocket style. The addressing scenario still seems not to be relevant for what's in focus.
  • Daniel Serodio
    Daniel Serodio almost 7 years
    Both Perl and PHP use =>. I'd guess that Ruby, being heavily inspired by Perl, borrowed the syntax from Perl :)
  • MasterLuV
    MasterLuV over 4 years
    What is different between "obj[:key]" vs "obj["key"]" in Ruby