include、extend、prepend 都可以拿來引用模組(module)內的方法,他們主要的差異如下:
範例:
module Animal
def sleep
puts "好睏,想睡了"
end
end
class Cat
include Animal
end
sweety = Cat.new
sweety.sleep
上述範例從 Cat 類別 include Animal,所以會讓 Cat 類別的實體繼承 Animal 的方法,讓 Cat 類別的實體可以使用。
最後會印出好睏,想睡了。
範例:
module Animal
def sleep
puts "好睏,想睡了"
end
end
class Cat
extend Animal
end
Cat.sleep
上述範例從 Cat 類別 extend Animal,所以會對 Cat 類別新增 Animal 的方法,讓 Cat 類別可以使用。
最後會印出好睏,想睡了。
範例:
module Animal
def sleep
puts "好睏,想睡了"
end
end
class Cat
include Animal
end
puts Cat.ancestors
使用 ancestors 方法可以印出該類別或模組的祖宗十八代,也就是印出所有他的上層類別及引入的模組。
上述範例會依序印出 Cat、Animal、Object、Kernel、BasicObject,
可以看到 Animal 模組會在 Cat 類別的上方。
範例:
module Animal
def sleep
puts "好睏,想睡了"
end
end
class Cat
prepend Animal
end
puts Cat.ancestors
上述範例會依序印出Animal、Cat、Object、Kernel、BasicObject,
可以看到 Animal 模組會在 Cat 類別的下方。
當 cat 呼叫 a 方法時,因為在 C 類別找不到方法,會往上層找,這時候 A 有 include 模組也有自己的上層, 他會優先去找模組內的 a 方法,而不是 B 類別的 a 方法。
範例:
module A
def a
puts "我是A模組"
end
end
class B
def a
puts "我是B類別"
end
end
class C < B
include A
end
cat = C.new
cat.a
上述範例會印出我是A模組
參考:
[1]Ruby Metaprogramming筆記(3): singleton method與singleton class
[2]Ruby Modules: include vs extend vs prepend
[3]include v.s extend 以及 require 的差別
[4]ruby.doc:ancestors