【问题标题】:How is ruby on rails has_many (and similar) implemented?ruby on rails has_many(和类似的)是如何实现的?
【发布时间】:2012-02-25 22:53:41
【问题描述】:

我正在分析 Rails 源代码,因为我想了解 has_many 和类似结构的内部工作原理。

到目前为止,我能够找到该方法的实现位置 (link to github):它在模块 ActiveRecord::Associations 中

def has_many(name, options = {}, &extension)
  Builder::HasMany.build(self, name, options, &extension)
end

这最终在 ActiveRecord::Associations::Builder::CollectionAssociation 类中结束 (link to github)

def self.build(model, name, options, &extension)
  new(model, name, options, &extension).build
end

我的 ruby​​ 技能到此为止了,我无法进一步跟踪它并找到“新”实施的地方以及它的作用。

有人可以指出我正确的方向,也许可以评论一下,引擎盖下发生了什么?

【问题讨论】:

  • +1 用于仔细阅读您正在使用的工具的源代码,以便更深入地了解它们的内部结构。好样的。
  • @s.m.:我同意。如果阅读源代码没有“显示研究成果”(正如赞成按钮的工具提示所说),我不知道是什么! +1!
  • 感谢大家的回答。我接受了 Jörg 的回答,因为它最详细。我也 +1 Baldrik 和 s.m.因为是第一个回答的人。

标签: ruby-on-rails ruby implementation has-many


【解决方案1】:

基本上,new 是这样定义的:

class Class
  def new(*args, &block)
    obj = allocate

    obj.initialize(*args, &block)
    # *actually* obj.send(:initialize, *args, &block) since initialize is private

    obj
  end
end

allocate 是这样定义的:

class Class
  def allocate
    # magic stuff for creating an empty object which cannot be expressed in Ruby:

    new_obj = Deep::Within::VM.__somehow_magically_allocate_memory__!

    new_obj.__class__ = self

    new_obj
  end
end

【讨论】:

    【解决方案2】:

    new 调用当前类的构造函数。构造函数是方法initialize,它是在CollectionAssociation 类中的self.build 方法之后定义的。它是纯 Ruby (ruby guide)

    【讨论】:

      【解决方案3】:

      为了扩展@Baldrick 的正确答案,newClass 中定义为类方法和实例方法,因此可用于所有类。

      new 所做的是调用allocateinitialize(假设已定义initialize 方法)。

      【讨论】:

      • 我不认为new 被定义为类方法。 Class 类是其自身的一个实例(耶,循环!),这就是 Class.new 起作用的原因。
      • @JörgWMittag 我不是 Ruby 内部的专家,但如果我没记错的话,文档显示 new 既是类又是 Class 的实例方法。
      • 其实就是Class#initialize的文档。 RDoc 只是显示它作为Class::new 的文档。它对 all 类执行此操作,因为这就是您通常使用 initialize 方法的方式。你实际上并没有调用它,你有 new 为你调用它。如果您查看源代码,您会发现文档块位于对应于 Class#initialize 方法的 rb_class_initialize 函数的顶部。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多