7

最近我偶然发现了这篇非常有趣的帖子:http ://opensoul.org/blog/archives/2011/02/07/concerning-activesupportconcern/ ,其中介绍了(并解释了)ActiveSupport::Concern源代码。

出现了一些问题,但最重要的是:

显然,有一个方法被称为append_features(至少在文档中)说:“Ruby 的这个方法的默认实现会将这个模块的常量、方法和变量添加到基本模块中”

我一直认为模块在方法查找链的意义上与类的工作方式相同 - 唯一的区别是你不能从中实例化对象,并且它没有被定义为这个类的“超类”(因为一个模块实际上不是一个类)。这意味着当一个类includes成为模块时,该模块只是作为直接父级添加到类的继承层次结构中,因此,将在模块中查找包含类中缺少的方法。

但如果是这种情况,那么append_features实际上“将方法添加到基本模块”是什么意思,这意味着您实际上可以通过覆盖此方法(ActiveSupport::Concern实际上确实如此)来防止这种行为。

有人可以在我的脑海中创建一些订单吗?

4

1 回答 1

10

基本上,它append_features是——或者应该被认为是——一种深入内部的 ruby​​ 方法

Module.include方法被定义为(在名为 的“eval.c”文件中rb_mod_include作为一个循环,它只为传递给它的每个参数调用mod.append_features(然后)。mod.includedModule

默认append_features实现rb_mod_append_features在“eval.c”文件中)调用rb_include_module,这是执行实际工作的方法。

(实际上真正真正的工作是由include_modules_at下面的几行完成)

这意味着您完全正确地说您可以通过覆盖(至少如果您不调用) 来阻止或破坏这个基本的 ruby​​ 功能。append_featuressuper

ActiveSupport::Concern实际调用,super只是在某些情况下,它会推迟实际调用,直到“相关”模块包含在某个“非相关”模块中。

通常最好重写included方法而不是append_features. 被included定义为 just "return nil",因此破坏任何东西的概率较小。这就是该included方法的文档所建议的。

于 2014-03-07T17:59:20.097 回答