>> include Daffy
>> include Bunny
>> end
>> p Foo.new.name
"Bunny"
>> Foo.ancestors
=> [Foo, Bunny, Daffy, Object, Kernel]
这个ancestors方法返回的数组里元素的顺序已经反映出答案。
再看下面的例子:
>> include Bunny
>> include Daffy
>> end
>> p Bar.new.name
"daffy"
>> class Too
>> def name
>> "Too foo bar"
>> end
?> include Bunny
>> include Daffy
>> end
>> p Too.new.name
"Too foo bar"
当类Too本身已经实现了name方法,则不会找module里mixin的name方法。
下面例子可以看到include和extend的区别
>> include Bunny
>> extend Daffy
>> end
>> p FooBar.new.name
"Bunny"
>>p FooBar.name
“daffy”
include 方式mixin的方法是作为实例方法使用的。
而extend方式则是类方法。
>> include Bunny
>> end
>> b = BarFoo.new
>> b.extend Daffy
>> b.name
=> "daffy"
>> p BarFoo.ancestors
[BarFoo, Bunny, Object, Kernel]
上面的例子说明,extend实际是有向某特定的对象追加模块的功能.extend被称为面向特殊类的include。
>> include Bunny
>> end
>> f = Foooo.new
>> f.extend Daffy
>> f.name
=> "daffy"
>> p Foooo.new.name
"Bunny"
>> Foooo.extend Bunny
>> p Foooo.new.name
"Bunny"
>> Foooo.extend Bunny
>> Foooo.name
=> "Bunny"
上面的例子,为类Foooo里添加了同为name的实例方法和类方法。
下面的例子也实现同样的功能。
>> include Bunny
>> extend Bunny
>> end
>> p Barr.new.name
"Bunny"
>> p Barr.name
"Bunny"
>> p Barr.ancestors
[Barr, Bunny, Object, Kernel]
我们看看下面的例子:
>> def a
>> puts "i m in Module"
>> end
>> end
>> module A
>> extend self
>> end
=> A
>> A.a
i m in Module
一句extend self, 直接让module 里的所有方法变成了module的类方法。
下面的例子效果和这是一样的。就不多说了。
>> def self.b
>> puts "i m in b in module"
>> end
>> end
>> A.b
i m in b in module
=> nil
>> module A
>> class < self
>> def c
>> puts "i m in c"
>> end
>> end
SyntaxError: compile error
(irb):109: syntax error, unexpected '<'
class < self
^
from (irb):113
>> module A
>> class << self
>> def c
>> puts "i m in c"
>> end
>> end
>> end
=> nil
>> A.c
i m in c
=> nil
>> module B
>> def aa
>> "aa in B"
>> end
>>
?> def bb
>> "bb in B"
>> end
>>
?> extend self
>> end
=> B
>> B.aa
=> "aa in B"
>> B.bb
=> "bb in B"
>> module C
>> extend self
>> def cc
>> "cc in B"
>> end
>>
?> def dd
>> "dd in B"
>> end
>> end
=> nil
>> C.cc
=> "cc in B"
>> C.dd
=> "dd in B"