【问题标题】:How to memoize all instances of a class without repeated code?如何在不重复代码的情况下记住一个类的所有实例?
【发布时间】:2021-02-04 21:11:36
【问题描述】:

我正在使用Memoist,并且我有一个特殊情况,我的班级的所有方法都需要记忆。我希望能够记住它们而无需为每种方法编写memoize :instance_method_name。我想做类似的事情:

class MyClass
  extend Memoist

  def initialize
    instance_methods(false).each(&:memoize)
  end

  private

  def method1
  end

  def method2
  end

  def method3
  end
end

当然它不起作用,因为instance_methods 无效。

【问题讨论】:

    标签: ruby memoization


    【解决方案1】:

    你只需要在正确的对象上调用方法:

    class MyClass
      extend Memoist
    
      private
    
      def method1
      end
    
      def method2
      end
    
      def method3
      end
    
      instance_methods(false).each(&method(:memoize))
    end
    

    Module#instance_methodsModule 类的实例方法,而不是MyClass 类的实例方法。因此,您需要在Module 的实例上调用它,而不是在MyClass 的实例上调用。

    同样,您在Symbol 的实例上调用Memoist#memoize,但您需要在Memoist 的实例上调用它,即在本例中为MyClass

    请注意,即使您编写的代码确实有效,它也不会按照您的想法执行。 memoize 通过用包装和缓存旧方法的新方法替换方法来工作。但是,如果您的代码按照您希望的方式运行,每次您创建一个新对象,它都会调用memoize再次,从而包装已经包装的方法,然后包装已经包装的方法的包装器,再包装已经包装的方法的包装器的包装器,以此类推。

    【讨论】:

    • each(&:memoize) 会在 Symbol 的实例上调用 memoize,也许您要使用 each(&method(:memoize))
    • 谢谢。我盲目地从 OP 中复制了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-25
    • 1970-01-01
    • 2021-09-11
    • 2017-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多