這篇就來好好了解一下 Ruby 中的模組吧,先來用個我最愛的超級英雄蜘蛛人當成例子
以前面人類類別的例子,我希望他可以有吐絲的能力來當蜘蛛人,可能會想用以下這些做法:
第1種的方式感覺在邏輯上比較奇怪,人為了吐絲就要去繼承蜘蛛,感覺就跟原本設定的類別有點衝突;第2種是直接寫在內部確實也可以達到同樣效果,但如果其他類別也需要用到這項能力就要另外在寫,沒辦法抽出來共用。
如果我們能夠把這些超級能力抽出來,需要使用再引入,不是很好嗎?
於是就有了模組的概念可以來解決這樣的狀況!
module 後面接上模組名稱,命名規則與 class 相同,使用駝峰大寫,下面就可以定義內部要有的方法。
如果在其他類別內要引用就使用 include
。
# 定義吐司模組
module spinning
def spin
puts "我會吐絲啦!"
end
end
# 引入模組到人類類別
class Human
include spinning # 引入吐絲模組
end
Sean = Human.new
Sean.spinning # 我會吐絲啦!
在類別中引入模組就可以讓新建立的實體 Sean 直接可以使用模組內的方法了。
class Dog
include spinning
end
如果建立一個狗類別也想要使用只要引入他也可以有這項能力。
在 Ruby 裡,「類別」的上層類別就是「模組」,也可以算是一種類別。
可以進入 irb 透過 supercalss 來看到 Class 的上層就是 Module
3.1.2 :001 > Class.superclass
=> Module
比較兩者的差異:
在 irb 中類別及模組後面加上.instance_methods,就可以查到所有內部具有的實體方法,將兩者相減可以知道差異
3.1.2 :002 > Class.instance_methods - Module.instance_methods
=> [:allocate, :superclass, :subclasses, :new]
下層的 Class 類別,比 Module 類別多了 4 個方法,其中 allocate 及 new 造就以下的差異:
如果你發現你要使用功能,可能在很多不同體系的類別裡都會用得到,那你可以考慮把功能寫在模組裡,需要的時候再 include 進來。