新手问题 append_features 与 included 的区别?

ibachue · 2012年09月30日 · 最后由 lgn21st 回复于 2020年04月22日 · 7932 次阅读

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 了。 如:

  1. append_features: http://apidock.com/ruby/Module/append_features
  2. included http://apidock.com/ruby/Module/included

从文档上看,很多时候你应该优先考虑 included, 我一般用到的场景是再给 class 加 methods 的时候会用到。对于 append_features,我认为文档已经很清楚了。还是一个 hook。只是比 included 要提前调用,Maz 提到会增加灵活性,我还是没明白。只能待查了。

这是超纲内容啊!

#5 楼 @hooopo 喝 哪里超纲了 说不定我将来面试 Ruby 程序员第一道题就是这个

#6 楼 @iBachue 1.一点儿幽默感也木有 2.考这么冷门问题的面试官是想干什么呢?拿自己刚刚看到的生僻内容难为别人?还是因为应聘者太强了,其他内容都非常熟悉了?

@hooopo 有道理,面试就应该少问那些非常生僻的内容

#7 楼 @hooopo 好吧 其实只是冷笑话而已

挖个坟 @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 来保证继承链能统一作用到最终目标类上。不知道我理解的对不对?

#10 楼 @qhwa 哈 这坟挖的够深的。。

时隔 7 年这个帖子被我再次发现!其实我倒觉得append_featuresincluded比较好区别,在不了解实情前容易蒙蔽的是append_featuresinclude的关系。一楼大哥 @lgn21st 的概括,在 stackoverflow 上找到了一个详细版本,供发现这个帖子的朋友们参考,Ruby modules and Module#append_features explanation ,加上 Matz 的澄清应该就算是一个比较圆满的答案了。

oatw 回复

七年....

需要 登录 后方可回复, 如果你还没有账号请 注册新账号