Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 353
lulalala Avatar asked Sep 01 '16 10:09

lulalala


People also ask

What can be a Hash key in Ruby?

A Hash is a dictionary-like collection of unique keys and their values. Also called associative arrays, they are similar to Arrays, but where an Array uses integers as its index, a Hash allows you to use any object type. Hashes enumerate their values in the order that the corresponding keys were inserted.

How do you write a Hash in Ruby?

In Ruby you can create a Hash by assigning a key to a value with => , separate these key/value pairs with commas, and enclose the whole thing with curly braces.

Is Ruby a Hash?

In Ruby, Hash is a collection of unique keys and their values. Hash is like an Array, except the indexing is done with the help of arbitrary keys of any object type. In Hash, the order of returning keys and their value by various iterators is arbitrary and will generally not be in the insertion order.


2 Answers

That's an irb issue, not Ruby.

bash=> ruby -e "puts({if: 1})"
bash=# {:if=>1}

You can use pry instead. It will read input correctly.

https://github.com/pry/pry

like image 174
fl00r Avatar answered Oct 19 '22 05:10

fl00r


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.

like image 41
Jörg W Mittag Avatar answered Oct 19 '22 06:10

Jörg W Mittag