是否有一个方法调用的记忆化公约?(Is there a convention for memoiza

2019-08-01 07:51发布

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

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的多行的方法呢?

Answer 1:

我会做这样的:

def filesize
  @filesize ||= calculate_filesize
end

private

def calculate_filesize
  # ...
end

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



Answer 2:

还有一个办法,更多Java风格,我认为。

首先,你应该实现批注,如“ Java风格的注解在红宝石 ”和“ 如何模拟类似Java的注释Ruby中? ”。

那么你应该添加注释像_cacheable将到方法,它应该返回实例变量表示,如果它是空应该通过调用方法计算的话,那么你的代码将更加清晰:

_cacheable
def some_method
   # do_some_work
end


Answer 3:

我用的是memoist宝石,它可以让你轻松memoize的一种方法,而无需改变你原来的方法或创建两个方法。

因此,例如,而不是有两种方法, file_sizecalculate_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 ...



Answer 4:

我通常使用begin, end按您的第一个例子,但如果有更多的代码,我只是看,如果变量存在,没有必要建立另一种方法只是为了这一点。

def some_method
  return @some_method if @some_method
  # lot's of code
  @some_method
end


Answer 5:

我不喜欢的一声无论是。 我用

def some_method 
  @some_method_memo ||= some_method_eval 
end 

private 

def some_method_eval
  # lot's of code 
end 

这里eval是速记evaluation 。 我喜欢这样的读取和也,它使公共接口简洁的方式。

我鄙视那些依赖下划线作为识别标志,约定:它们都容易出错,要求我记得YAMC(另一种意义的约定)。 Ada语言,专为安全关键型应用,不允许前置,或多个下划线。 好主意。



Answer 6:

我通常不喜欢它在阿吉斯答案或:

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,其中可能会慢得多 。



文章来源: Is there a convention for memoization in a method call?