Ruby メタプログラミングを理解し始めたばかりです。ミックスイン/モジュールはいつも私を混乱させます。
- include : 指定されたモジュールメソッドをターゲットクラスのインスタンスメソッドとしてミックスインします
- extend : 指定されたモジュールメソッドをターゲットクラスのクラスメソッドとしてミックスインします
では、大きな違いはこれだけでしょうか、それとももっと大きなドラゴンが潜んでいるのでしょうか?
module ReusableModule
def module_method
puts "Module Method: Hi there!"
end
end
class ClassThatIncludes
include ReusableModule
end
class ClassThatExtends
extend ReusableModule
end
puts "Include"
ClassThatIncludes.new.module_method # "Module Method: Hi there!"
puts "Extend"
ClassThatExtends.module_method # "Module Method: Hi there!"
ベストアンサー1
extend - 指定されたモジュールのメソッドと定数をターゲットのメタクラス(つまりシングルトンクラス)に追加します。例:
- を呼び出すと
Klazz.extend(Mod)
、KlazzはModのメソッド(クラスメソッドとして)を持つようになります。 - を呼び出すと
obj.extend(Mod)
、obj には Mod のメソッド (インスタンス メソッドとして) が含まれますが、 の他のインスタンスにはobj.class
それらのメソッドが追加されません。 extend
パブリックメソッドです
include - デフォルトでは、指定されたモジュールのメソッドをターゲットモジュール/クラスのインスタンスメソッドとしてミックスインします。例:
- を呼び出すと
class Klazz; include Mod; end;
、KlazzのすべてのインスタンスがModのメソッド(インスタンスメソッドとして)にアクセスできるようになります。 include
コンテナ クラス/モジュール内から呼び出されることを意図しているため、プライベート メソッドです。
ただし、モジュールは、メソッドにモンキーパッチを適用することで の動作をオーバーライドする ことがよくあります。これは、従来の Rails コードで非常に顕著です。include
included
詳細はイェフダ・カッツまで。
の詳細な説明とinclude
、デフォルトの動作については、次のコードを実行したと仮定します。
class Klazz
include Mod
end
- ModがすでにKlazzまたはその祖先のいずれかに含まれている場合、includeステートメントは効果がありません。
- また、衝突しない限り、KlazzのModの定数も含まれています。
- これにより、KlazzはModのモジュール変数にアクセスできるようになります。例
@@foo
:@@bar
- 循環的なインクルードがある場合、ArgumentError が発生します。
- モジュールを呼び出し元の直接の祖先としてアタッチします (つまり、Mod を Klazz.ancestors に追加しますが、Mod は Klazz.superclass.superclass.superclass のチェーンには追加されません。そのため、
super
Klazz#foo を呼び出すと、Klazz の実際のスーパークラスの foo メソッドをチェックする前に Mod#foo がチェックされます。詳細については、RubySpec を参照してください)。
もちろん、ルビーコアドキュメントこうしたものを探すには、ここが最適な場所です。RubySpec プロジェクト機能性が正確に文書化されていたので、これも素晴らしいリソースでした。