在方法调用中是否存在memoization约定?

我想避免重新评估方法调用中的值。 直到现在,我这样做:

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 / non-memoized对方法是否有其他约定?
  • 是否有一些惯例来记忆多行方法?

我会这样做:

 def filesize @filesize ||= calculate_filesize end private def calculate_filesize # ... end 

所以我只是以不同的方式命名方法,因为我觉得它更有意义。

还有一种方法,我认为更多Java风格。

首先,您应该实现注释,例如“ Ruby中的Java样式注释 ”和“ 如何 在Ruby 中模拟类似Java的注释? ”。

然后你应该添加像_cacheable这样的注释,它会告诉它应该返回实例变量的方法,如果它是null,它应该通过调用方法来计算它,所以你的代码会更清楚:

 _cacheable def some_method # do_some_work end 

我使用memoist gem,它可以让你轻松地记忆方法,而无需改变原始方法或创建两种方法。

因此,例如,不要使用两个方法file_sizecalculate_file_size ,而必须使用实例变量自己实现memoization:

 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 

这里evalevaluation简写。 我喜欢这种读取的方式,并且它使公共界面简洁。

我鄙视依靠下划线作为区别标记的惯例:它们都容易出错,需要我记得YAMC(又一个毫无意义的惯例)。 Ada语言专为安全关键型应用程序而设计,不允许使用前导,尾随或多个下划线。 好主意。

我通常在Agis的答案或者:

 def filesize() @filesize ||= calculate_filesize end 

BTW:

我经常使用这种记忆技术:

 def filesize() @_memo[:filesize] ||= calculate_filesize end 

这将允许您稍后使用一个简单的@_memo.clear清除所有已记忆的变量。 @_memo变量应该像这个Hash.new { |h, k| h[k] = Hash.new }一样初始化 Hash.new { |h, k| h[k] = Hash.new } 。 它为您提供了许多使用ActiveSupport :: Memoize和类似元编程技术的冒险,这些技术可能要慢得多 。