编写多行懒惰计算方法的ruby方法是什么?

我认为我可能不会以最ruby的方式编写懒惰的实例化方法/属性。 以此方法为例:

def tax @tax ||= Proc.new do if flat_tax > commission_plan.tax_max return commission_plan.tax_max end if commission_plan.tax_max if flat_tax < commission_plan.tax_min return commission_plan.tax_min end if commission_plan.tax_min flat_tax end.call end 

是否有一种更像ruby的方法来重构这种方法?

 def tax @tax ||= calc_tax end private def calc_tax min, max = commission_plan.tax_min, commission_plan.tax_max if (min..max).include? flat_tax flat_tax else flat_tax > max ? max : min end end 

你在问什么叫做Memoization。 正如Yuri建议的那样,你使用Proc这个很尴尬。

这是我的快速重构。 我可能仍然会进一步重构……但这是一个简单的重构,更多的是Ruby-ish。

 def tax @tax ||= calculate_tax end def calculate_tax if commission_plan.tax_max && flat_tax > commission_plan.tax_max commission_plan.tax_max elsif commission_plan.tax_min && flat_tax < commission_plan.tax_min commission_plan.tax_min else flat_tax end end 

此外,如果您不介意包含一些外部依赖项,请查看ActiveSupport :: Memoizable 。 这是一篇关于memoization的文章。

如果您不想向外部库添加依赖项,则可以轻松添加自己的“memoize”帮助程序。 有点像:

 class Class def memoize(method) original_method = instance_method(method) instance_var = "@__#{method}__".to_sym define_method(method) do |*a,&b| cached = instance_variable_get(instance_var) unless cached cached = old_method.bind(self).call(*a,&b) instance_variable_set(instance_var, cached) end cached end end end 

然后用法就像:

 def tax # expensive calculation here end memoize :tax 

如果您不喜欢这个memoize界面,可以将其更改为您喜欢的任何内容。 这是Ruby,宝贝! 你可以像泡泡糖一样扭曲,弯曲和伸展的语言。 也许像这样的界面会很好:

 def_memoized :tax do # expensive calculation here end 

我喜欢将我的每个项目扩展项放在一个名为lib/core_extensions.rb的文件中。 这是那种可以进入那里的东西。

我不明白你为什么要创建这个匿名函数。 这是……多余的。 这是一个更好,更清洁的代码:

 def tax return commission_plan.tax_max if commission_plan.tax_max && flat_tax > commission_plan.tax_max return commission_plan.tax_min if commission_plan.tax_min && flat_tax > commission_plan.tax_min return flat_tax end 

还有其他方法可以实现它,但与你在那里相比,这是一个很大的改进。