我使用以下钩子来检查当我做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
或inspect
,我得到通常的对象符号:#<Object:0x007fae0a87ac48>
.
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
完全不同的方法。