2012年10月27日 星期六

[宅] 宅男臥軌日記(2) - ruby中的include, extend及require

include vs. extend

在ruby的世界中,class只能單一繼承,而為了保有彈性,ruby提供了module的概念。
module是一個method的集合,可讓class去混入(mixin)一個module來取得這些method,而mixin的過程可用include或extend來達到。
但是include和extend的差別在哪?我們可以從以下的程式碼得知:

module Foo
  def foo
    puts 'heyyyyoooo!'
  end
end


class Bar
  include Foo
end

Bar.new.foo # heyyyyoooo!
Bar.foo # NoMethodError: undefined method ‘foo’ for Bar:Class


class Baz
  extend Foo
end

Baz.foo # heyyyyoooo!
Baz.new.foo # NoMethodError: undefined method ‘foo’ for #<Baz:0x1e708>

簡而言之,include是讓這個class所產生的instance繼承module中的method,有點javascript中function.prototype的味道。
extend則是讓這個class具有module中的method,卻不會繼承給instance。


require

在講require之前必須先提到load,load的作用在於將不同檔案的module給mix進來,概念上類似於C的include。而require的作用就類似於load,只是在require只會mix一次,當發現之前已經mix過同一個檔案時,require就會回傳false。
require相對load會少掉不必要的mix動作,但在module時常被更新的狀態下,最好使用load來確保自己抓到的檔案是最新的。