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

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.

Leave a Comment