Today I Learned

hashrocket A Hashrocket project

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:)

This code essentially boils down to:

def ticket
  @ticket = @ticket || Ticket.find_by(owner:)

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:)
See More #ruby TILs
Looking for help? Each developer at Hashrocket has years of experience working with Ruby applications of all types and sizes. We're an active presence at Ruby conferences, have written some of the most popular gems, and have worked on many of the web's Ruby on Rails success stories. Contact us today to talk about your Ruby project.