在Rubinius中实现mixins在哪里?

Sła*_*osz 3 ruby rubinius

在Rubinius源代码中,负责包含模块的代码是什么?(具体来说,将模块放置为对象类的超类.)

Jör*_*tag 8

如果您查看文档Module#include,您会发现它委托给Module#append_features:

Module.append_features以相反的顺序调用每个参数.

Module#append_features反过来,该文档(非常简要地)描述了默认的Ruby mixin算法的工作原理:

当这个模块包含在另一个模块中时,Ruby调用append_features此模块,将接收模块传递给它mod.Ruby的默认实现是将此模块的常量,方法和模块变量mod添加到此模块尚未添加到mod其祖先或其中一个祖先的位置.另见Module#include.

如果你看一下Module#append_featuresRubinius的源代码,你会发现这是一个别名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
Run Code Online (Sandbox Code Playgroud)

所以,最后,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)
  ...
Run Code Online (Sandbox Code Playgroud)

你的具体问题:

确切地将模块放置为对象类的超类

这个循环中回答:

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
Run Code Online (Sandbox Code Playgroud)

注意insert_at.