Ruby 模块和 Module#append_features 解释

标签 ruby inheritance module

最近我碰到了这个非常有趣的帖子: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_featuresincluded 定义为"return nil",因此破坏任何东西的可能性较小。这就是 included 方法文档的建议。

关于Ruby 模块和 Module#append_features 解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17007098/

相关文章:

sql-server - 如何通过 tiny_tds 将文件插入到 sql-server?

python - 在两个线程之间传递值

java - 父类(super class)中的实例变量有什么用,以及如何在子类中更改它们的值

c++ - 无法通过可变参数函数将函数指针传递给父类中的方法——编译器错误?

Python 3.x : how to use ast to search for a print statement

ios - 我们可以限制 Swift 生成的接口(interface)只能在 Xcode 中从模块访问吗?

ruby - 如何停止 AmazonAWS 上的程序?

ruby - 检查 Appium 中是否显示具有不同文本大小写的元素并执行相应的逻辑

windows - 如何使用 Node 的调试模块(Windows)?

ruby - 在 Ruby 中下载 Azure Blob 时出现 NoMemoryError