Ruby中’include’和’prepend’有什么区别?

来自模块

模块#append_features(mod)→mod =>当这个模块包含在另一个模块中时,Ruby在这个模块中调用append_features,并在mod中传递接收模块。 Ruby的默认实现是将此模块的常量,方法和模块变量添加到mod,如果此模块尚未添加到mod或其祖先之一。

模块#prepend_features(mod)→mod =>当这个模块被放在另一个模块中时,Ruby在这个模块中调用prepend_features,并在mod中传递接收模块。 Ruby的默认实现是将此模块的常量,方法和模块变量覆盖到mod,如果此模块尚未添加到mod或其祖先之一。

任何人都可以帮助我理解以下问题:

  • Module哪些更多function被定义为appendprepend除了那些默认值?

  • 他们的function如何不同?

  • 何时使用append_featuresprepend_features

  • 上面两条粗线之间有什么区别?

  • Module的哪些function被定义为append和prepend?

正如您引用的文字中所述:

常量,方法和模块变量

  • 他们的function如何不同?

两者都将混合模块的方法添加到传递的模块(类)中。 不同之处在于这些方法的查找顺序,如果目标类已经定义了它们:

include表现得好像目标类inheritance了混合模块:

 module FooBar def say puts "2 - Module" end end class Foo include FooBar def say puts "1 - Implementing Class" super end end Foo.new.say # => # 1 - Implementing Class # 2 - Module 

prepend使得混合模块中的方法“更强”并首先执行它们:

 module FooBar def say puts "2 - Module" super end end class Foo prepend FooBar def say puts "1 - Implementing Class" end end Foo.new.say # => # 2 - Module # 1 - Implementing Class 

这个例子从这里扯下来: http : //blog.crowdint.com/2012/11/05/3-killer-features-that-are-coming-on-ruby-2-0.html

  • 何时使用append_features和prepend_features?

如果要将目标模块(类)的方法保留在方法查找链的末尾,请使用prepend

通过在SO中搜索rubymoduleprepend ,可以找到一些真实的例子:

  • 覆盖模块中另一个定义的方法
  • 当猴子修补方法时,你能从新实现调用重写方法吗?
  • Ruby:模块,Mixins和Block令人困惑?

(注意:我只提到方法,因为它们在inheritance和混合时最容易想象,但这同样适用于其他function。)

我想把它添加为@Mladen Jablanovic已经提出的一个好答案的评论,但我不能因为我的低声望点。

我在post上发现了一个更简洁,更清晰,更具描述性的答案 – Ruby模块:Include vs Prepend vs Extend我在这里发布它,以防有人需要它并且可以用更少的努力来获得它。

直接引用:

虽然include是将外部代码导入类的最常用方法,但Ruby还提供了另外两种实现方法:扩展和前置。 但是,它们根本没有相同的行为,这些差异经常被Ruby开发人员误解。

要了解如何使用它们,我们必须首先深入了解Ruby如何使用称为祖先链的东西解析在运行时执行的方法。

创建Ruby类时,它包含一个常量名称列表,它们是它的祖先。 它们是类inheritance的所有类,以及它们包含的模块。 例如,通过在String类上调用祖先,我们得到其祖先的列表:

 String.ancestors => [String, Comparable, Object, PP::ObjectMixin, Kernel, BasicObject] 

include是导入模块代码最常用和最简单的方法。 在类定义中调用它时,Ruby会将模块插入到类的祖先链中,就在它的超类之后。

从Ruby 2开始提供,Rubyists比其他两个朋友更不了解prepend。 它实际上像include一样工作,除了它不是在链中的类和它的超类之间插入模块,而是将它插入到链的底部,甚至在类本身之前。

我建议阅读post以获得更好的理解,因为它附带了示例。