【发布时间】:2020-08-09 11:31:27
【问题描述】:
在 Ruby 编程语言中,我正在创建一个带有类级宏的类,如下所示:
class Timer
def self.add_time
def time
STDERR.puts Time.now.strftime("%H:%M:%S")
end
end
end
类方法add_time在执行时会生成一个time方法。
现在,我可以在另一个类Example 中执行该类级宏,如下所示:
class Example < Timer
add_time
end
当我现在在 Example 类的实例上调用 time 时,time 方法就如我所愿:
ex = Example.new
ex.time
并打印当前时间:23:18:38。
但现在我想将add_time 宏放在一个模块中,仍然具有相同的整体效果。我尝试使用这样的include:
module Timer
def self.add_time
def time
STDERR.puts Time.now.strftime("%H:%M:%S")
end
end
end
class Example
include Timer
add_time
end
ex = Example.new
ex.time
然后我收到一个错误,指出方法 add_time 未在类 Example:NameError: undefined local variable or method ‘add_time’ for Example:Class 上定义。因此,我尝试使用 extend,而不是像这样:
class Example
extend Timer
add_time
end
但它给了我一个类似的错误。
所以问题是:我怎样才能获得与原始示例中相同的效果,其中 Timer 被定义为类,但使用模块代替?
【问题讨论】:
-
当一个类包含一个模块时,模块的实例方法成为该类的实例方法。当一个类扩展一个模块时,模块的实例方法成为该类的类方法。在执行这两个操作时,模块的模块方法都被忽略了。
-
@CarySwoveland 所以你的意思是
self.add_time方法在包含或扩展时会被忽略,因为它不是实例方法而是模块方法? -
我可以通过将
def add_time定义为模块的实例方法来使其工作,然后执行Example.include Timer。然后我需要做ex.add_time将time方法添加到实例ex。但这不是我想要的,因为我希望time方法可用于我的Example类的所有实例。 -
是的,回答您的第一条评论。关于第二种,将
add_time设为Timer的实例方法,如你所说,然后Example.extend Timer将add_time设为Example的类方法。 -
@CarySwoveland 我也试过了,但它似乎不起作用。有一个模块
Timer和一个实例方法add_time。然后执行Example.extend Timer使add_time成为Example的类方法。最后,致电Example.add_time。但是,当我这样做时,方法time被定义为类方法,而不是实例方法。所以ex.time仍然不起作用。但是,我确实通过巧妙地使用class_eval找到了一个似乎可行的解决方案。我会把它作为我的解决方案发布。感谢您帮助我找到解决方案。
标签: ruby reflection module include extend