Mix-in
モジュールをクラスに挿入する方法
モジュールの特色
・単独ではインスタンス化出来ない
・継承できない
・クラスや他のモジュールに取り込み事が出来る
module Bar def medhodA end end
p Bar.ancestors # [Bar] p Bar.instance_methods #["methodA"]
include
classに取り込む
class FooExt < Foo include Bar end
FooExt.ancestors # [FooExt, Bar, Foo, Object, Kernel] FooExt.superclass # Foo FooExt.insttance_method(false) # ["method2"]
Mix-inによる、仮想的継承の順
includeした順に親クラスの後に継承したような形となる
class FooExt < Foo include Bar include Bar2 end
- 宣言は Foo, Bar, Bar2, FooExtの順で、後になるほど同一名のメソッド機能が優先される
extend
インスタンス化された変数にextendでモジュールを挿入する
foo1 = Foo.new foo2 = Foo.new foo1.extend(Bar) foo1.methodA #BarのmethodAが実行される foo2.methodB #NoMethodError
- foo1インスタンスにBarモジュールを挿入する
- foo2には影響しない
クラス定義での例
module M4 def method1; 1; end end class C4 include M4 extend M4 end C4.method1 #クラスメソッドとして実行 c4 = C4.new #extendが実行され無名クラスのメソッド扱いになる c4.method1
モジュール関数
module Foo def method1 puts "1" end module_function :method1 end Foo.method1 1
モジュール特異メソッド
インスタンスを生成しないまま使える
module Foo def Foo.method1 puts "1" end def self.method2 puts "2" end end Foo.method1 1 Foo.method2 2
include時、特異メソッドはインクルードされない
module Foo def Foo.method1 puts "1" end end class Bar include Foo end Bar.method1 #NoMethodError
モジュール関数はincludeされる
module Foo def method1 puts "1" end module_function :method1 end class Bar include Foo end obj = Bar.new obj.method1 1 Bar.method1 #Error