Effective Ruby
#1 (Almost) Everything is true
- Every value is
true
exceptfalse
andnil
. - The number zero is
true
in Ruby. - Use the
nil?
method to differentiate betweenfalse
andnil
.
#2 All objects could be nil
- Coerce
nil
objects into the expected type (eg useto_i
andto_s
). Array#compact
/Hash#compact
removes all nil elements.Array#dig
/Hash#dig
returns nil if any intermediate step is nil.
#3 -
#4 Constants are mutable
- Always freeze constants to prevent them form being mutated (eg
TIMEOUT = 5.freeze
).
#5 -
#6 -
super
#7 Different behaviours of - When you override a method from inheritance hierarchy the
super
keyword can be used to call the overriden method. - Using
super
with no arguments and parentheses is equivalent to passing it all of the arguments that were given to the enclosing method. - If you want to use
super
without passing the overriden method any arguments, you must use empty parentheses (egsuper()
).
#8 -
#9 -
Struct
for structured data
#10 - When dealing with structured data which doesn't quite justify a new lass prefer using
Struct
toHash
. - Assign the return value of
Struct::new
to a constant and treat that constant like a class (egReading = Struct.new(:date, :high, :low)
)
#11 -
#12 Different flavors of equality
- Never ovveride the
equal?
method. It's expected to strictly compare objects and returntrue
only if they're both pointers to the same object in memory (have the sameobject_id
). - The
Hash
class uses theeql?
method to compare objects used as keys during collisions. The default implementation probably doesn't do what you want. You need to implement<=>
, then aliaseql?
to==
and write a sensiblehash
method. - Use the
==
operator to test if two objects represent the same value. case
expressions use the===
operator to test eachwhen
clause. The left operand is the argument given towhen
and the right operand is the argument given tocase
.
<=>
and the Comparable
module
13 Compare via - Implement object ordering by defining a
<=>
operator and including theComparable
module. - The
<=>
operator should returnnil
if the left operand can't be compared with the right.
14 -
15 Class instance variables over class variables
- Prefer class instance variables to class variables.
- Classes are objects and so have their own private set of instance variables.
16 Duplicate collections before mutating them
- Method arguments are passed as references, not values (except
Fixnum
objects). - Duplicate collections passed as arguments before mutating them, eg
@collection = collection.dup
. - The
dup
andclone
methods only create shallow copies. For most objects,Marshal
can be used to create deep copies.