I’ve been reviewing my coding skills in Ruby to keep myself sharp and thought I’d write a post about some gotchas that I came across during my studies.
== === .eql? .equal?
Even newbies to Ruby know what ==
does. It’s an operator that compares the value of two operands.
a = 1
b = 1
a == b
=> true
b = 2
a == b
=> false
But what if we want to be more discriminating about our comparison? The ==
only compares values and doesn’t check the Class of the objects. How do we also for the same Class? If you come from a Javascript background, you might be inclined to say ===
. BUT WAIT
a = 1
a.class
=> Fixnum
b = 1.0
=> Float
a == b
=> true
a === b
=> true
It turns out ===
in Ruby and Javascript behave differently. If you’d like to compare value AND class in ruby, you have to invoke the method .eql?
, while ===
is used to compare the class of the object, usually in when
clauses of case
statements.
a, b = 1, 1
a.eql? b
=> true
b = 1.0
a.eql? b
=> false
Fixnum === a
=> true
Float === b
=> true
Fixnum === b
=> false
Finally when we want to compare if an object is the very same object, as in they not just have the same value and class, but also the same object_id
, we use the .equal?
method.
a = 'Hello World!'
b = 'Hello World!'
a == b
=> true
a.eql? b
=> true
a.equal? b
=> false # !!! but why? Check the object_id
a.object_id
=> 70270346064520
b.object_id
=> 70270346044960 # Not the same object!
b = a
a.equal? b
=> true # if we check the object_id of both a and b they will return the same object
Order of Operations and Precedence
This question came up on a sample interview question. Consider the following
x = true && false
=> false
y = true and false
=> false
# what is the value of x and y
Although both statements return false
, the value of y
is actually true
. In ruby &&
has a higher precedence than =
in the order of operations and and
has a lower precedence than =
. So what ends up happening is more like following
x = ( true && false) # x = false
( y = true ) and false # y = true, then false is run as a separate statement on its own
So keep in mind you should use &&
and ||
for comparisons and and
and or
for flow control.