ハロの外部記憶インターフェイス

そろそろ覚える努力が必要かも…

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"]
  1. BarのメソッドはFooExtのメソッドとしては表示されない
  2. 理由はFooExtがインスタンス化されるタイミングでBarが無名クラスとして作成される為
  3. そのため、インスタンス化した後は実行が可能になる

Mix-inによる、仮想的継承の順

includeした順に親クラスの後に継承したような形となる

class FooExt < Foo
  include Bar
  include Bar2
end
  1. 宣言は Foo, Bar, Bar2, FooExtの順で、後になるほど同一名のメソッド機能が優先される

extend

インスタンス化された変数にextendでモジュールを挿入する

foo1 = Foo.new
foo2 = Foo.new
foo1.extend(Bar)
foo1.methodA  #BarのmethodAが実行される
foo2.methodB  #NoMethodError
  1. foo1インスタンスにBarモジュールを挿入する
  2. foo2には影響しない

クラス定義での例

module M4
  def method1; 1; end
end
class C4
  include M4
  extend M4
end

C4.method1    #クラスメソッドとして実行
c4 = C4.new    #extendが実行され無名クラスのメソッド扱いになる
c4.method1
  1. クラスメソッドでは内部の対象メソッドが実行される
  2. extendはインスタンス生成時に適用されるため、インスタンスのメソッド扱いになり、クラスメソッドとは別のものとなる

モジュール関数

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