どうもこんにちは。
include
とprepend
とextend
。Ruby初学者であれば誰もがつまづくでしょう。
簡単に解説します。(出力結果を比較しながら眺めてみてください。)
基本的な動作
include
とprepend
は大きく変わりません。この二つは、モジュール内のメソッドをインスタンスメソッドとして使用するためにインクルードするためのメソッドです。
extend
は、モジュール内のメソッドをクラスメソッドとして使用するためにインクルードするためのメソッドです。
include
module Test_a
def method_1
puts 'method_1'
end
end
class Test_b
include Test_a
end
Test_b.new.method_1 #=> method_1
prepend
module Test_a
def method_1
puts 'method_1'
end
end
class Test_b
prepend Test_a
end
Test_b.new.method_1 #=> method_1
extend
module Test_a
def method_1
puts 'method_1'
end
end
class Test_b
extend Test_a
end
Test_b.method_1 #=> method_1
include
とprepend
のややこしい探索順
よくRubyGoldの問題で問われるのが、継承チェーンの探索順ですが、include
とprepend
の違いはここにあります。
include
を使用した例
include
を使用した場合、Person
クラスのgreet
メソッドが先に見つかります。
module Greetings
def greet
"Hello from Greetings module!"
end
end
class Person
include Greetings
def greet
"Hello from Person class!"
end
end
person = Person.new
puts person.greet #=> Hello from Person class!
prepend
を使用した例
include
を使用した場合、Greetings
モジュールのgreet
メソッドが先に見つかります。
module Greetings
def greet
"Hello from Greetings module!"
end
end
class Person
prepend Greetings
def greet
"Hello from Person class!"
end
end
person = Person.new
puts person.greet #=> Hello from Greetings module!
extend self
という記述をしている問題が出てきた...
module Test_a
def method_1
puts 'method_1'
end
end
module Test_m
include Test_a
extend self # classでは`extend self`でエラーになるので注意!
end
Test_m.method_1 #=> method_1
Test_m.new.method_1 #=> undefined method `new' for Test_m:Module (NoMethodError)
extend self
が実行された場合、Test_m
モジュール自身に対して自身のインスタンスメソッドをクラスメソッド(モジュールメソッド)として追加しています。