I’ve been asked a few times recently why I prefer Ruby’s hash rockets to the “new” or “1.9” hash syntax. I figured I’d document it for posterity. I’m aware this is like an extremely unpopular take. This is my opinion, I hope you give it the time to think about it. If you disagree, that’s fine! I’m just outlining why I like my Hash Rockets.

One syntax for everything

Consider the following hash:

{
  :abc => "def",
}

Now, we could express that as:

{
  abc: "def",
}

and certainly, that’s all very well and good. Let’s consider though, what if we want a hash of strings:

{
  "abc" => "def",
}

or integers

{
  123 => User.new,
}

or arrays

{
  ["user", 123] => "bees",
  ["team", 1978] => "1997",
}

we can’t do that with the new hash syntax.

When I’m thinking about writing materially any software, I want to use consistent constructs for each thing I’m trying to do. When I’m writing hashes in Ruby, the Hash Rocket syntax gives me that. I can’t express every hash that I want with the new hash syntax. If I need to convert a hash with symbol keys to a hash with string keys, which I think is a common operation, I don’t have to rotate the whole syntax, just the type. In terms of simplicity: it also lets me put any expression on either side, not just a weird “symbol like” thing.

Works like JSON

Consider:

>> JSON.parse(<<EOD
{
  "abc": 123
}
EOD
)
=> {"abc" => 123}

more specifically:

>> JSON.parse(<<EOD
{
  "abc": 123
}
EOD
) != {
"abc": 123
}

The new hash syntax allows quoted keys. This makes it look almost identical to JSON. However, it doesn’t produce a string key, but a symbol. This means it doesn’t roundtrip cleanly through JSON.parse. The hashrocket syntax, when used with symbol keys does correctly survive a round trip through JSON. I’ve personally been confused by this behavior a number of times.

Looks like Ruby

Personally, I find the hash rocket syntax much more readable, because you have an expression, the => and another expression, I feel like it’s very easy to read. One of the things I find really hard to read is:

{
  abc: :def
}

when you have two symbols next to each other, I somehow find it much harder to parse out than:

{
 :abc => :def
}

wherein this looks like two very normal symbol constructions, with a clean separator.

Works with keyword arguments

>> def foo(a:)
>> p a
>> end
=> :foo
>> foo(:a => :b)
:b

If you’re a fan of keyword args, you can use the Hash Rocket syntax with it too.

This is the most unpopular take in Ruby

Probably! This is kind of just my opinion. I don’t think you’re a bad person if you disagree with me. I really like Hash Rockets because they allow me to use one syntax to express every hash, to use keyword arguments, to round trip hashes through JSON, and generally can be used as a consistent construct within Ruby, which the old syntax can’t. Thanks for reading!