只是想了解一下Ruby元编程。mixin/模块总是让我感到困惑
- include:将指定的模块方法作为实例方法混入目标类中
- extend:将指定的模块方法作为类方法混入目标类中
那么主要的区别是这条龙还是潜伏着一条更大的龙
e、 g
模块可重用模块
def模块法
将“模块方法:您好!”
终止
终止
包括的类
包括可重用模块
终止
扩展的类
扩展可重用模块
终止
放入“包括”
ClassThatIncludes.new.module#方法#“模块方法:您好!”
将“扩展”
ClassThatExtends.module#方法#“模块方法:您好!”
extend-将指定模块的方法和常量添加到目标的元类(即singleton类)
e、 g
- 如果调用
Klazz.extend(Mod),现在Klazz有Mod的方法(作为类方法) - 如果调用
obj.extend(Mod),现在obj有Mod的方法(作为实例方法),但是obj.class的其他实例中没有添加这些方法 extend是一种公共方法
include-默认情况下,它在目标模块/类中混合指定模块的方法作为实例方法。
e、 g
- 如果你调用
类Klazz;包括国防部;结束,现在Klazz的所有实例都可以访问Mod的方法(作为实例方法) include是一个私有方法,因为它是从容器类/模块中调用的
然而,模块通常通过猴子修补包含的方法来覆盖包含的行为。这在遗留Rails代码中非常突出。更多详情请参见Yehuda Katz
关于的更多详细信息包括,以及它的默认行为,假设您运行了以下代码
类Klazz
包括国防部
终止
- 如果Mod已经包含在Klazz或其祖先之一中,则include语句无效
- 它还包括Klazz中的Mod常量,只要它们不冲突
- 它允许Klazz访问Mod的模块变量,例如
@@foo或@@bar - 如果存在循环包含,则引发ArgumentError
- 将模块附加为调用方的直接祖先(即,它将Mod添加到Klazz.祖先,但Mod未添加到Klazz.superclass.superclass.superclass.superclass的链中。因此,在Klazz#foo中调用
super,将在检查Klazz真正的超类的foo方法之前检查Mod#foo。有关详细信息,请参阅RubySpec)
当然,ruby核心文档始终是实现这些功能的最佳场所。RubySpec项目也是一个极好的资源,因为它们精确地记录了功能
#包括RubySpec rubydoc#包括RubySpec rubydoc#扩展RubySpec-rubydoc- 扩展的RubySpec rubydoc
#扩展对象RubySpec rubydoc#附加功能RubySpec rubydoc