lulalala lulalala - 3 months ago 6
Ruby Question

Why Rails can use `if` as hash key but not in Ruby

In pure Ruby irb, one cannot type

{if: 1}
. The statement will not terminate, because irb thinks
if
is not a symbol but instead the beginning of an if statement.

So why can Rails have
before_filter
which accept if as parameters? The guide have codes like:

class Order < ApplicationRecord
before_save :normalize_card_number, if: :paid_with_card?
end


Same thing happens to
unless
as well.

Answer

IRb's parser is well-known to be broken. (In fact, the very bug you encountered was already reported months ago: Bug #12177: Using if: as symbol in hash with new hash syntax in irb console is not working.) Just ignore it. There are also other differences in behavior between IRb and Ruby, semantic ones, not just syntactic. E.g. methods defined at the top-level are implicitly public instead of implicitly private as they should be.

IRb tries to parse the code with its own parser to figure out, e.g. whether to submit it to the engine when you hit ENTER or wait for you on the next line to continue the code. However, because Ruby's syntax is extremely complex, it is very hard to parse it correctly, and IRb's parser is known to deviate from Ruby's.

Other REPLs take different approaches, e.g. Pry actually uses Ruby's parser instead of its own.

Comments