3

Rubiniusソースのどこにモジュールを含める責任があるコードがありますか?(具体的には、モジュールをオブジェクトクラスのスーパークラスとして配置します)。

4

1 に答える 1

8

のドキュメントを見ると、次の場所Module#includeに委任されていることがわかりますModule#append_features

Module.append_features各パラメータを逆の順序で呼び出します。

次に、のドキュメントではModule#append_features、デフォルトのRubyミックスインアルゴリズムがどのように機能するかを(非常に簡単に)説明しています。

このモジュールが別のモジュールに含まれている場合、Rubyはappend_featuresこのモジュールを呼び出し、受信モジュールをに渡しますmodmodRubyのデフォルトの実装では、このモジュールがまだ追加されていない場合、modまたはその祖先の1つに、このモジュールの定数、メソッド、およびモジュール変数を追加します。も参照してくださいModule#include

Rubiniusのソースコードを見るとModule#append_features、それが次のエイリアスであることがわかります。Module#include_into

# Called when this Module is being included in another Module.
# This may be overridden for custom behaviour. The default
# is to add constants, instance methods and module variables
# of this Module and all Modules that this one includes to +klass+.
#
# See also #include.
#
alias_method :append_features, :include_into

それで、最後にModule#include_into、本物です:

# Add all constants, instance methods and module variables
# of this Module and all Modules that this one includes to +klass+
#
# This method is aliased as append_features as the default implementation
# for that method. Kernel#extend calls this method directly through
# Module#extend_object, because Kernel#extend should not use append_features.
def include_into(klass)
  ...

あなたの特定の質問:

モジュールをオブジェクトクラスのスーパークラスとして正確に配置する

このループで答えられます:

k = klass.direct_superclass
while k
  if k.kind_of? Rubinius::IncludedModule
    # Oh, we found it.
    if k == mod
      # ok, if we're still within the directly included modules
      # of klass, then put future things after mod, not at the
      # beginning.
      insert_at = k unless superclass_seen
      add = false
      break
    end
  else
    superclass_seen = true
  end

  k = k.direct_superclass
end

に注意してinsert_atください。

于 2011-10-08T09:18:35.357 に答える