I want to avoid reevaluation of a value in method call. Untill now, I was doing this:
def some_method
@some_method ||= begin
# lot's of code
end
end
But it ends up quite ugly. In some code, I saw something like the following:
def some_method
@some_method ||= some_method!
end
private
def some_method!
# lot's of code
end
I don't like the bang (!
) at the end, so I came up with this:
def some_method
@some_method ||= _some_method
end
private
def _some_method
# lot's of code
end
I would do it like this:
def filesize
@filesize ||= calculate_filesize
end
private
def calculate_filesize
# ...
end
So I'd just name the method differently, as I think it makes more sense.
There is one more way, more Java-style I think.
First of all you should implement annotations, like "Java-style annotations in Ruby" and "How to simulate Java-like annotations in Ruby?".
Then you should add annotation like _cacheable that will said to method that it should return instance variable and if it is null it should calculate it by invoking method, so your code will be more clear:
_cacheable
def some_method
# do_some_work
end
I use the memoist gem, which lets you easily memoize a method without having to alter your original method or create two methods.
So for example, instead of having two methods, file_size
and calculate_file_size
, and having to implement the memoization yourself with an instance variable:
def file_size
@file_size ||= calculate_file_size
end
def calculate_file_size
# code to calculate the file size
end
you can just do this:
def file_size
# code to calculate the file size
end
memoize :file_size
Each memoized function comes with a way to flush the existing value.
object.file_size # returns the memoized value
object.file_size(true) # bypasses the memoized value and rememoizes it
So calling object.file_size(true)
would be the equivalent of calling object.calculate_file_size
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With