最近我碰到了这个非常有趣的帖子:http://opensoul.org/blog/archives/2011/02/07/concerning-activesupportconcern/遍历(并解释)ActiveSupport::Concern
源代码。
出现了一些问题,但最重要的是:
显然有一个名为 append_features
的方法(至少在文档中是这样)说:“Ruby 对此方法的默认实现会将此模块的常量、方法和变量添加到基模块”。
我一直认为模块在方法查找链的意义上与类的工作方式相同 - 唯一的区别是您不能从中实例化对象,并且它没有定义为此类的“父类(super class)”(因为一个模块实际上不是一个类)。这意味着当一个类 includes
一个模块时,该模块只是作为直接父类添加到该类的继承层次结构中,因此,将查找包含类中缺少的方法在模块中。
但如果是这样的话,那么 append_features
实际上“向基本模块添加方法” 意味着什么,这意味着您实际上可以防止这种行为,通过重写此方法(ActiveSupport::Concern
实际上是这样做的)。
有人可以在我的脑海中建立一些秩序吗?
最佳答案
基本上,append_features
是——或者应该被认为是——一种深层内部 ruby 方法。
Module.include
方法被定义(在名称为 rb_mod_include
的“eval.c”文件中) 作为一个循环,它只调用 mod.append_features
(然后是 mod.included
),用于传递给它的每个 Module
参数。
默认的append_features
实现(“eval.c”文件中的rb_mod_append_features
),调用rb_include_module
,这是真正起作用的方法。
(实际上真正的工作是由下面的 include_modules_at
几行完成的)
这意味着你完全正确地说你可以通过覆盖 append_features
来阻止或破坏这个基本的 ruby 功能(至少如果你不调用 super
)。
ActiveSupport::Concern
实际上调用了 super
,只是在某些情况下它推迟了实际调用,直到“相关”模块被一些“非相关”模块包含"一个。
通常最好覆盖 included
方法而不是 append_features
。 included
定义为"return nil"
,因此破坏任何东西的可能性较小。这就是 included
方法文档的建议。
关于Ruby 模块和 Module#append_features 解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17007098/