環境
Ruby 2.6
はじめに
includeとextendの使い方については、Rubyの文法書を読めばたいてい書いてありますが、簡単に言えば次のようになります。
モジュールに記述したメソッドをクラスに取り込む際に、
-
クラスメソッドとして取り込む場合(つまり、取り込むクラスがクラスメソッドとして定義している場合)は、extendを使って取り込みます。
-
インスタンスメソッドとして取り込みたい場合(つまり、取り込むクラスがインスタンスメソッドとして定義している場合)は、includeを使って取り込みます。
文法書を読めば、「なるほど、それだけの話か」だけで終わってしまいますが、一応、手を動かして動作を確認してみないと、本当に理解したことにはなっていないものです。プログラミングは頭だけで理解するのでなく、手を動かして体で理解することが何よりも大事だと思っています。ということで、includeとextendの違いを実際に動かして確認してみましょう。
動作確認(その1)
つぎのようなモジュールを作成します。
module Test_module
def mod_test
puts "OK"
end
end
モジュールをクラスメソッドとして取り込みます。ここで、extend Test_moduleの代わりに、include Test_moduleと記述すればエラーになります。メソッドを呼び出さずに、includeだけする分にはエラーにはなりません。因みに、extend Test_moduleは、class << selfの上に記述します。class << selfの下に記述すればエラーになります。
class Test_class
extend Test_module
class << self
def cls_cls_test1
mod_test
end
end
end
ここように、モジュールに記述したメソッドが、クラスメソッドとして呼び出すことができるようになります。
$Test_class.cls_cls_test1
=> OK
$Test_class.mod_test
=> OK
動作確認(その2)
次は、モジュールをインスタンスメソッドとして取り込みます。そのためには、include Test_moduleと記述して取り込みます。extend Test_moduleと記述すればエラーになります。
class Test_class
include Test_module
def cls_cls_test1
mod_test
end
end
このように、インスタンスメソッドとして呼び出すことができるようになります。
$Test_class.new.cls_cls_test1
=> OK
$Test_class.new.mod_test
=> OK