2
Foo = Module.new

class MyClass
  include Foo
end

モジュールがクラスに含まれると、匿名プロキシ クラスが作成され、MyClass のスーパークラスとして設定されます。

MyClass.ancestors => [MyClass, Foo, ...]

しかし、モジュールが拡張されると内部で何が起こるのでしょうか? Ruby はこれをどのように処理しますか?

4

4 に答える 4

5

あなたが尋ねているのはObject#extend

したがってextend、 を使用すると、任意のモジュールのメソッドをそのオブジェクトに含めることができます。たとえば、HelperModule というモジュールがあります。

module HelperModule
  def foo
    puts "from module helper"
  end
end

使用例1:

obj = Object.new
obj.extend HelperModule
obj.foo                  # => "from module helper"

使用例 2:

class MyClass
  extend HelperModule
end
MyClass.foo              # => "from module helper"

内部的には、 Metaprogramming Rubyによると:

Object#extend() は、レシーバーの固有クラスにモジュールを含める単純なショートカットです。


ruby のメソッド call の簡単な説明:

  1. オブジェクトのクラスを見つけ、そこにメソッドが定義されているかどうかを確認します
  2. そのクラスのスーパークラスを見つけ、そこにメソッドが定義されているかどうかを確認します

obj 
 |
 | class
 |                     superclass                  superclass
 --->  ObjectClass  --------------> SuperClass1 --------------> SuperClass2 ....

固有クラスとメソッド呼び出しパスについての詳細な説明は、このすばらしい本Metaprogramming Rubyを参照してください。

ありがとう

于 2013-07-26T05:09:36.010 に答える
0

モジュールが Ruby で拡張されると、内部で何が起こりますか?

モジュールMがクラスにインクルードされると、メソッド テーブル ポインタが のメソッド テーブルを指すようCに、匿名プロキシ クラス(インクルード クラス⟦M′⟧と呼ばれる) が作成されます。(定数テーブルとモジュール変数についても同じです。)のスーパークラスは のスーパークラスに設定され、 のスーパークラスは に設定されます。M⟦M′⟧CC⟦M′⟧

また、M他のモジュールが含まれる場合、プロセスは再帰的に適用されます。

実際、これはデフォルトの動作です。実際に起こるのはのinclude呼び出しであり、そのメソッドをオーバーライドすることM.append_features(C)ですべての動作をカスタマイズできます。

Rubiniusのソース コードはModule#append_features非常に読みやすいと思います。

于 2013-02-12T14:15:40.577 に答える
0

obj.extend SomeModuleと同じですobj.eigenclass.include SomeModule(: これは単なる疑似コードですが、アイデアは得られます...)。

于 2013-07-26T07:34:36.877 に答える