我想避免在方法调用的值的重新评估。 直到如今,我这样做:
def some_method
@some_method ||= begin
# lot's of code
end
end
但它最终很丑陋。 在一些代码,我看到类似如下:
def some_method
@some_method ||= some_method!
end
private
def some_method!
# lot's of code
end
我不喜欢的感叹号( !
到了最后,所以我想出了这个):
def some_method
@some_method ||= _some_method
end
private
def _some_method
# lot's of code
end
- 用下划线前面加上一个好习惯?
- 是否有memoized /非memoized对方法的一些其他公约?
- 有一些约定,以memoize的多行的方法呢?
我会做这样的:
def filesize
@filesize ||= calculate_filesize
end
private
def calculate_filesize
# ...
end
所以我只是名称的方式有所不同,因为我觉得它更有意义。
还有一个办法,更多Java风格,我认为。
首先,你应该实现批注,如“ Java风格的注解在红宝石 ”和“ 如何模拟类似Java的注释Ruby中? ”。
那么你应该添加注释像_cacheable将到方法,它应该返回实例变量表示,如果它是空应该通过调用方法计算的话,那么你的代码将更加清晰:
_cacheable
def some_method
# do_some_work
end
我用的是memoist宝石,它可以让你轻松memoize的一种方法,而无需改变你原来的方法或创建两个方法。
因此,例如,而不是有两种方法, file_size
和calculate_file_size
,并不必自己与一个实例变量实现记忆化:
def file_size
@file_size ||= calculate_file_size
end
def calculate_file_size
# code to calculate the file size
end
你可以这样做:
def file_size
# code to calculate the file size
end
memoize :file_size
每个memoized功能配备了一个方法来刷新现有的值。
object.file_size # returns the memoized value
object.file_size(true) # bypasses the memoized value and rememoizes it
因此调用object.file_size(true)
将调用相当于object.calculate_file_size
...
我通常使用begin, end
按您的第一个例子,但如果有更多的代码,我只是看,如果变量存在,没有必要建立另一种方法只是为了这一点。
def some_method
return @some_method if @some_method
# lot's of code
@some_method
end
我不喜欢的一声无论是。 我用
def some_method
@some_method_memo ||= some_method_eval
end
private
def some_method_eval
# lot's of code
end
这里eval
是速记evaluation
。 我喜欢这样的读取和也,它使公共接口简洁的方式。
我鄙视那些依赖下划线作为识别标志,约定:它们都容易出错,要求我记得YAMC(另一种意义的约定)。 Ada语言,专为安全关键型应用,不允许前置,或多个下划线。 好主意。
我通常不喜欢它在阿吉斯答案或:
def filesize() @filesize ||=
calculate_filesize
end
BTW:
我经常用这个记忆化技术:
def filesize() @_memo[:filesize] ||=
calculate_filesize
end
这将允许您以后清除所有memoized变量与一个简单的@_memo.clear
。 所述@_memo变量应该初始化这样Hash.new { |h, k| h[k] = Hash.new }
Hash.new { |h, k| h[k] = Hash.new }
。 它给你很多使用的ActiveSupport :: memoize的和类似的编程元技术的320282,其中可能会慢得多 。