I wrote a script that contains a few method definitions, no classes and some public code. Some of these methods execute some pretty time-consuming shell programs. However, these shell programs only need to be executed the first time the method is invoked.
Now in C, I would declare a static variable in each method to make sure those programs are only executed once. How could I do that in Ruby?
There is an idiom in ruby:
x ||= y.
def something @something ||= calculate_something end private def calculate_something # some long process end
But there is a problem with this idiom if your 'long running utility' may return a false value (false or nil), since the
||= operator will still cause the right side to be evaluated.
If you expect false values then use an additional variable, in a way similar to the proposed by DigitalRoss:
def something return @something if @something_calculated @something = calculate_something @something_calculated = true return @something end
Don't try to save a line of code by setting the @something_calculated variable first, an then running calculate_something. If your calculate function raises an exception your function will always return nil and will never call the calculate again.
More generally, in Ruby you use instance variables. Note however, that they are visible in all the methods of given object - they are not local to the method.
If you need a variable shared by all instances, define the method in the class object, and in every instance call
class User def self.something @something ||= calculate_something end def self.calculate_something # .... end def something self.class.something end end