Memoization the Right Way
Dealing with nil values
The ||=
conditional assignment operator is one of Ruby's most elegant pieces of syntax. In a statement like this...
@my_variable ||= expensive_operation
It reads, "if my_variable
is falsey, assign the result of expensive_operation
, otherwise return the value of my_variable
".
The problem here lies with the test for falseyness. If expensive_operation
returns a nil then because nil is falsey the value won't be cached. It will be evaluated each time instead which might be wasteful.
The better way to deal with this is to first test if a variable has been defined.
return @my_variable if defined?(@my_variable)
@my_variable ||= expensive_operation
(defined?
is actually a keyword, not a method call, so it's very fast but has has very low precedence so always use parenthesis to make sure you're evaluating the right thing)
Member discussion