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
=> falseBut 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
=> trueIt 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
=> falseFinally 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 objectOrder 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 yAlthough 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 ownSo keep in mind you should use && and || for comparisons and and and or for flow control.