Featured image

If you’ve been working with Ruby for a while, you’ve probably come across lazy initialization in your projects (it’s actually one of my favorite techniques in Ruby). In most cases, this is a single-line call using the ||= operator, for example: @value ||= some_method. But what if you have a sequence of code that needs to run just once to compute and return the final value? In that case, you can wrap that logic in a begin…end block. Also, don’t forget that if the return value can be nil or false, a simple ||= will re-evaluate on every single call. To handle this, you need to add a guard clause using defined?. And of course, you can always use one of the dedicated gems for this: memoist, memoizable, or memo_wise.

How do you implement lazy initialization in your own projects?

module MyLib
  def self.value
    @value ||=
      begin
        # complex operation of getting the value
        sleep(5)
        'value'
      end
  end

  def self.value_nil_or_false
    return @value_nil_or_false if defined?(@value_nil_or_false)
    @value_nil_or_false ||=
      begin
        # complex operation of getting the value
        sleep(5)
        nil # or false
      end
  end
end

va = MyLib.value # the next call will return the cached value
vn = MyLib.value_nil_or_false # here nil and false also cached