我使用以下钩子检查正在执行包含的模块include Foo
:
module Foo
def self.included(includer)
puts includer
end
end
Module#include
在模块(通常使用它)与顶层的行为不同。在模块内部,self
是模块,它是Module
的实例。当我致电include
时,执行包含的模块是 self
:
module Bar
puts self # => Bar
include Foo # => includer: Bar
end
在ruby脚本的顶层,self
是main
,是Object
的一个实例。当我在顶层致电include
时,包含的模块是Object
, self
的类别:
puts self # => main
include Foo # => includer: Object
有人可以解释原因吗?
顶级对象必须是特殊的;如果我在其上调用to_s
或inspect
,则会显示main
,但如果我使用Object.new
创建另一个对象并调用to_s
或{{1}在它上面,我得到了通常的对象表示法:inspect
。
答案 0 :(得分:1)
main
是特殊的,并具有其自己的include
定义。也就是说,其singleton_class具有自己的include
定义。要证明这一点:
irb(main):017:0> method(:include).owner
=> #<Class:#<Object:0x007fc0398c6468>>
irb(main):018:0> self.singleton_class
=> #<Class:#<Object:0x007fc0398c6468>>
您要考虑的include
是在Module
上定义的:
MyClass.method(:include).owner
=> Module
因此,include
在“顶层”上的行为有所不同,也就是在我们称为main
的对象上,这是最简单的原因:与Module#include
完全不同