Ruby の include と extend の違いは何ですか? 質問する

Ruby の include と extend の違いは何ですか? 質問する

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 コードで非常に顕著です。includeincluded詳細はイェフダ・カッツまで

の詳細な説明とinclude、デフォルトの動作については、次のコードを実行したと仮定します。

class Klazz
  include Mod
end
  • ModがすでにKlazzまたはその祖先のいずれかに含まれている場合、includeステートメントは効果がありません。
  • また、衝突しない限り、KlazzのModの定数も含まれています。
  • これにより、KlazzはModのモジュール変数にアクセスできるようになります。例@@foo:@@bar
  • 循環的なインクルードがある場合、ArgumentError が発生します。
  • モジュールを呼び出し元の直接の祖先としてアタッチします (つまり、Mod を Klazz.ancestors に追加しますが、Mod は Klazz.superclass.superclass.superclass のチェーンには追加されません。そのため、superKlazz#foo を呼び出すと、Klazz の実際のスーパークラスの foo メソッドをチェックする前に Mod#foo がチェックされます。詳細については、RubySpec を参照してください)。

もちろん、ルビーコアドキュメントこうしたものを探すには、ここが最適な場所です。RubySpec プロジェクト機能性が正確に文書化されていたので、これも素晴らしいリソースでした。

おすすめ記事