Ruby memoization with nil values
As Ruby developers, we're often looking for ways to reduce time consuming lookups in our code. A lot of times, that leads us to memoizing those lookups with the common ||=
operator.
However, if our lookups return a nil or falsey value, our memo will actually keep executing the lookup:
def ticket
@ticket ||= Ticket.find_by(owner:)
end
This code essentially boils down to:
def ticket
@ticket = @ticket || Ticket.find_by(owner:)
end
If our find_by
in the example above returns nil, the code will continue to run the find_by
every time we call the ticket
method.
To avoid this, we can shift our pattern a bit, and look to see if we have already set our instance variable or not:
def ticket
return @ticket if defined?(@ticket)
@ticket = Ticket.find_by(owner:)
end
Tweet