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