ActiveSupport::Memoizable指的是哪种Ruby记忆化模式?

56

所以在Rails 3.2中,ActiveSupport::Memoizable已经被弃用。

消息的内容如下:

DEPRECATION WARNING: ActiveSupport::Memoizable is deprecated and
will be removed in future releases,simply use Ruby memoization
pattern instead.

它指的是"Ruby记忆化模式"(单数),好像有一种我们都应该知道和参考的模式...

我猜他们的意思是类似于:

def my_method
  @my_method ||= # ... go get the value
end
或者
def my_method
  return @my_method if defined?(@my_method)

  @my_method = # ... go get the value
end

我还有什么遗漏的吗?


1
如果你想要使用 Ruby 的 memoizable 保存 'false' 或 'nil',是不会生效的。因此,如果你想要实现自己的 memoizable 包装器,需要添加一种保存 'false' 和 'nil' 的方式。 - JB Juliano
顺便提一下(在这个古老的问题上跌跌撞撞),我已经提出“玫瑰记忆化”作为这种模式的名称:https://thepugautomatic.com/2016/01/rose-memoization/ - Henrik N
1
@HenrikN 我已经偶尔发现了你的博客。很高兴在这里遇见你。 - bodacious
4个回答

39

这里是Memoizable被弃用的提交(以及随后的讨论):https://github.com/rails/rails/commit/36253916b0b788d6ded56669d37c96ed05c92c5c

作者提倡使用@foo ||= ...的方法,并将这个提交作为迁移示例:https://github.com/rails/rails/commit/f2c0fb32c0dce7f8da0ce446e2d2f0cba5fd44b3

编辑: 请注意,我并不一定认为这个改变意味着所有的memoize实例都应该用这种模式替换。我认为这意味着Memoizable在Rails代码本身中不再需要或不再想要。正如评论所指出的那样,Memoizable远不止是一个@foo ||= ...的包装器。如果你需要这些功能,请继续使用Memoizable,只是你必须从ActiveSupport以外的地方获取它(我猜如果还没有人分叉一个gem版本的话,会有人这么做)。


33

另一个选择是使用Memoist gem:

它直接从ActiveSupport :: Memoizable中提取,并可用作一种即插即用的替代方法。 只需require 'memoist'并更改原来的代码即可。

extend ActiveSupport::Memoizable

转换成

extend Memoist

2

补充前面的答案,如果要对类方法进行记忆化,请使用以下模式:

class Foo
  class << self
    def bar
      @bar ||= begin
        # ...
      end
    end
  end
end

0

根据avaynshtok上面提到的提交的评论,我选择这个方案:

ActiveSupport::Deprecation.silence { extend ActiveSupport::Memoizable }

因为我想,如果Memoizable从ActiveSupport中删除了,我的RSpec套件就会在起跑线上立即崩溃。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接