如何为类方法动态定义别名方法?

我有一个模块可以调用“计算器”,我希望将其包含在“产品”类中。 计算器将扩展“Product”,它将类方法复制到Product上。 其中一个类方法是“memoize”。 这个想法是我可以做这样的事情:

module Calculator def self.extended(base) base.memoize :foo_bar end end 

为了记住方法(特别是类方法):foo_bar。 在memoize中我调用方法“alias_method”,它试图将类方法别名为另一个名称(这里:foo_bar)。 这失败了。 Memoize看起来像:

 module Calculator (the extended module) def memoize(name) alias_method "memoized_#{name}", name end end 

当通过memoize:foo_bar调用它时,alias_method行踢出错误,说Product没有方法“name”..我的理解是因为alias_method会尝试别名实例方法而不是类方法..(我不知道为什么但没什么大不了的)..

我可以像这样重新打开本征类

 module Calculator def memoize(name) class << self alias_method "memoized_#{name}", name end end end 

这可以工作,但名称不适用于类<< self definition的范围。 人们已经提到过使用self.class_eval和self.instance_eval,但这些似乎都不起作用..我也喜欢我的蛋糕并且也吃它..我怎么能保持alias_method动态但是在class_methods上使用它?

所以我才知道这会解决问题:

 module Calculator def memoize define_singleton_method(name, method(name)) end end 

然后,当Calculator包含在Product中时,它将根据需要定义单例方法。 我仍然不知道为什么alias_method只需要处理实例方法..而且我不知道为什么class_eval或instance_eval没有解决问题..但至少我有一个解决方案..

如果在include / extend之前将实例方法置为别名怎么办? 如果您将扩展名放在类名后面,则尚未定义实例方法。

 module Foo def self.extended(base) base.memoize :flavor end def memoize(name) alias_method "memoized_#{name}", name end end class Bar def flavor puts "Orange" end extend Foo end if __FILE__==$0 b = Bar.new b.memoized_flavor #=> Orange end