Foo = Module.new
class MyClass
include Foo
end
モジュールがクラスに含まれると、匿名プロキシ クラスが作成され、MyClass のスーパークラスとして設定されます。
MyClass.ancestors => [MyClass, Foo, ...]
しかし、モジュールが拡張されると内部で何が起こるのでしょうか? Ruby はこれをどのように処理しますか?
Foo = Module.new
class MyClass
include Foo
end
モジュールがクラスに含まれると、匿名プロキシ クラスが作成され、MyClass のスーパークラスとして設定されます。
MyClass.ancestors => [MyClass, Foo, ...]
しかし、モジュールが拡張されると内部で何が起こるのでしょうか? Ruby はこれをどのように処理しますか?
あなたが尋ねているのはObject#extend
したがってextend、 を使用すると、任意のモジュールのメソッドをそのオブジェクトに含めることができます。たとえば、HelperModule というモジュールがあります。
module HelperModule
def foo
puts "from module helper"
end
end
obj = Object.new
obj.extend HelperModule
obj.foo # => "from module helper"
class MyClass
extend HelperModule
end
MyClass.foo # => "from module helper"
内部的には、 Metaprogramming Rubyによると:
Object#extend() は、レシーバーの固有クラスにモジュールを含める単純なショートカットです。
ruby のメソッド call の簡単な説明:
obj
|
| class
| superclass superclass
---> ObjectClass --------------> SuperClass1 --------------> SuperClass2 ....
固有クラスとメソッド呼び出しパスについての詳細な説明は、このすばらしい本Metaprogramming Rubyを参照してください。
ありがとう
モジュールが Ruby で拡張されると、内部で何が起こりますか?
モジュールMがクラスにインクルードされると、メソッド テーブル ポインタが のメソッド テーブルを指すようCに、匿名プロキシ クラス(インクルード クラス⟦M′⟧と呼ばれる) が作成されます。(定数テーブルとモジュール変数についても同じです。)のスーパークラスは のスーパークラスに設定され、 のスーパークラスは に設定されます。M⟦M′⟧CC⟦M′⟧
また、M他のモジュールが含まれる場合、プロセスは再帰的に適用されます。
実際、これはデフォルトの動作です。実際に起こるのはのinclude呼び出しであり、そのメソッドをオーバーライドすることM.append_features(C)ですべての動作をカスタマイズできます。
Rubiniusのソース コードはModule#append_features非常に読みやすいと思います。
obj.extend SomeModuleと同じですobj.eigenclass.include SomeModule(注: これは単なる疑似コードですが、アイデアは得られます...)。