翻訳者のメモ:この投稿を読む前に、Rubyメタクラスを掘り下げた投稿にまず慣れることをお勧めします。すべてのルービストは、
includeおよび
extendの正式な定義に精通してい
ます 。 モジュール
インクルードを実行してクラスインスタンスメソッドを追加し、
拡張してクラスメソッドを追加します。 残念ながら、これらの定義は完全に正確ではありません。
インスタンスを使用する理由を説明できません
。 メソッドをオブジェクトに追加するには、
(モジュール)を
拡張します。 この場合、
インスタンスを使用するべきではありません
。 include (モジュール) ? この問題を理解するために、メソッドが保存されている場所を把握することから始めます。
私があなたのために保存するメソッドと私のメソッドを保存する人
Rubyのオブジェクトは独自のメソッドを保存しません。 代わりに、メソッドを保存するシングルトンクラスを作成します。
class A def self.who_am_i puts self end def speak_up(input) puts input.upcase end end
インタプリタはクラス
Aとそれに付随するシングルトンクラスを作成します(オブジェクトの名前の前にプレフィックス
'を使用してオブジェクトのシングルトンクラスを参照します)。 クラスインスタンスメソッド(
speak_upなど )は、クラス
Aに格納されているメソッドに追加されます
。 クラスメソッド(
who_am_iなど )はクラス
'Aに格納されます
。 A.singleton_methods

クラスインスタンスでも同じことが起こります。 クラス
Aのオブジェクトがあり、それにメソッドを追加する場合、このメソッドをオブジェクト自体の中に保存することはできません。 Rubyのオブジェクトは独自のメソッドを保存しないことに注意してください。
a = A.new def a.not_so_loud(input) puts input.downcase end
ここでも、オブジェクト「
a 」に対して
not_so_loudメソッドを
格納するシングルトンクラスが作成されます。

これで、オブジェクト「
a 」にのみ属し、クラス
Aの他のオブジェクトに影響を与えないメソッドができました
。私は父ですか?
クラス
Aには、オブジェクト「
a 」およびクラス
Aの他のすべてのオブジェクトに必要な継承チェーンに関するメソッドと情報が含まれています
。 同様に、シングルトンクラス
'Aには、クラス
Aのメソッドと継承チェーン情報が含まれています
。 クラス
Aをクラス
'Aのオブジェクトと見なすことができます
。 秘trickは、
「シングルトンクラスに直接アクセスできないことです。 これは、
Aと
'Aにメソッドを追加することを何らかの形で区別する必要があることを意味します
。 ここに
含まれて
拡張し 、遊びに来ます。
含む
モジュールをオブジェクトに
含める場合、オブジェクトの継承チェーンにメソッドを追加します。
class A include M end

これは、クラス
Aの祖先を確認することで簡単に確認できます
。 A.ancestors
伸ばす
extendは
includeと同じですが、オブジェクトのシングルトンクラス用です。
class A extend M end

また、クラス
'Aの先祖を確認することでこれを確認できます
。 A.singleton_class.ancestors
オブジェクトに
extendを使用
することもできます。
a = A.new a.extend(M) a.singleton_class.ancestors
拡張を単純にクラスメソッドを追加する方法と考える場合、これまでに行ったすべてのことはあまり意味がありません。 ただし、これをオブジェクトのシングルトンクラスにメソッドを追加する方法として見ると、上記の例がより明確になります。
フックが含まれています
各
include呼び出しは、
含まれるメソッドのプラグインをチェックします。 このメソッドは
、includeを使用してモジュールが接続されたときに実行され
ます 。 接続の
初期化コンストラクターのようなものです。 ご想像のとおり、
extendにはこれらの目的のための独自のメソッド
-extendedがあります。 そのため、クラスメソッドとクラスインスタンスメソッドの両方を一度に追加する場合、これに
含まれるフックを使用できます。
module M def self.included(base) base.extend(ClassMethods) end def speak_up(input) puts input.upcase end module ClassMethods def who_am_i puts self end end end class C include M end c = C.new
まず、クラス
Cの継承チェーンにモジュール
Mを含めます
。
次に、
'Cクラスの継承チェーンにメソッドを追加して、
Cクラスを拡張します。

おわりに
includeおよび
extendの一般的な使用よりも深く掘り始めると、奇妙で恐ろしいことがわかります。 ただし、基礎となる実装を理解することは価値があり、すべてがすぐに意味をなします。
インクルードを定義して
、もう一度
拡張してみましょう。
include-モジュールメソッドをオブジェクトに追加します。
extend-オブジェクトのシングルトンクラスの
include呼び出し。
インタープリターがどのように機能するかについてさらに詳しく
知りたい場合は、Ruby Internalsに関するPatrick Farleyのプレゼンテーションをご覧になることをお勧めします。
翻訳者注: instance.include(Module)を使用できないもう1つの点は、 includeメソッドがModuleクラスのプライベートメソッドであることです。 一般に、この記事を読む前に、 extendとincludeの作業も想像していなかったので、翻訳する価値があると考えました。
わかりやすく説明します。この記事でシングルトンクラスと呼ばれるものには、メタクラスと固有クラスという別の名前があります。 これは、Rubyコミュニティに「公式」名がまだない、まったく同じエンティティです。 私はシングルトンクラスを使用しました 元に近いです。 ただし、Matz(言語の作成者)は、用語eigenclassにより感銘を受けています。