Hi all, 类似这样的一段代码:
module M
def self.included(base)
puts "included #{base.inspect}"
end
def self.append_features(base)
puts "append_features #{base.inspect}"
end
end
class F
include M
end
最终结果是 append_features F included F
请问诸位,用 included 和 append_features 的区别在哪里?
http://www.velocityreviews.com/forums/t834205-append_features-vs-include.html 这里可以找到 Matz 本人对 include 和 append_features 这两个方法澄清。
我认为 included 可以当作 include 之后的的一个 callback,用户可以在这里 hook 一些定制代码,而 append_features 是在 include 这个方法背后真正干活的方法,而 include 本身其实也是一个类或者模块的 callback。
我换一种方式来尝试解答你,也给自己补上这一课。我看到楼主的问题后,我因为没用过 append_features,对它可以说是一无所知。一般这个时候,我会先看看回复,但说白了,我对@lgn21st @kenshin54 给的例子一点都不感冒。这个时候我会直接去看 API Doc 了。 如:
从文档上看,很多时候你应该优先考虑 included, 我一般用到的场景是再给 class 加 methods 的时候会用到。对于 append_features,我认为文档已经很清楚了。还是一个 hook。只是比 included 要提前调用,Maz 提到会增加灵活性,我还是没明白。只能待查了。
挖个坟 @iBachue
在读 rails 的源码,刚好看到了 ActiveSupport::Concern,里面同时用了这两个方法 https://github.com/rails/rails/blob/master/activesupport/lib/active_support/concern.rb#L105-L124
对照了一下 ruby 文档,append_features 更底层一些,通过重写可以阻止 ruby 默认的逻辑——添加常量、方法和 module variables 到目标类中。而 included 只是一个 hook。
ActiveSupport::Concern 用了 append_features 来保证继承链能统一作用到最终目标类上。不知道我理解的对不对?
时隔 7 年这个帖子被我再次发现!其实我倒觉得append_features
和included
比较好区别,在不了解实情前容易蒙蔽的是append_features
和include
的关系。一楼大哥 @lgn21st 的概括,在 stackoverflow 上找到了一个详细版本,供发现这个帖子的朋友们参考,Ruby modules and Module#append_features explanation ,加上 Matz 的澄清应该就算是一个比较圆满的答案了。