IRB - Ruby 1.9.x hash syntax: {if: true} is not equal to {:if => true}

hash, irb, ruby, ruby-1.9, ruby-1.9.3

Solution

It's challenging to reliably and unambiguously parse things in any language. This is especially true when you start using reserved words. And `irb` has to go beyond that and provide an interactive model on top of the parser, which is even harder. I personally don't think there's too much value in worrying about cases like this, either as a user of the language or as a maintainer. In my mind, it's better to simply figure out what works and avoid getting into these situations if possible.

You can see some similar behaviors in plain Ruby, outside `irb`. For example:

puts({if: true})  # no problem, behaves as expected in Ruby 1.9.3.
puts {if: true}   # raises a syntax error in Ruby 1.9.3

To answer your question, is it "expected behavior, a bug or a limitation", I'd say you should ignore `irb` and compare it to plain Ruby, and if you do this, it works fine. That means it has to be an `irb` bug.

But is it possible or worthwhile to solve? @coreyward makes a good point in his comment that `irb` has to delay execution in most cases when it encounters an `if`. You'd have to look further to know for sure, but you may not be able to unambiguously interpret all cases like this.

My advice: avoid this construct altogether if you can, and don't use reserved words for labels if you can avoid it!

Here's a file you can run with plain Ruby (eg MRI). You should see `{:if=>true}` in the output to confirm it works.

{if: true}
foo = {if: true}
# if MRI is working, should be able to execute this file without trouble.
p foo

Problem

Long story short, I was writing a method that included an options argument, that will do certain stuff if the value for the key :if, evaluated to true. When I trying the hash in IRB using the new syntax I got a syntax error in IRB, the prompt stays open: ``` 1.9.3p374 :010 > {if: true} 1.9.3p374 :011?> ``` Using the old syntax, works just fine: ``` 1.9.3p374 :011 > {:if => true} => {:if=>true} ``` All keywords that start a statement, exhibit the same behavior. E.g. `def`, `do`, `module`, `case` Other reserved words that occur in the middle and `class` work just fine: `else`, `end` My question is: Is this expected behavior, a bug or a limitation?

Original source