Gis*_*shu 397 ruby module include extend
刚刚开始关注Ruby元编程.mixin/modules总是让我困惑.
那么主要区别在于这还是潜伏着更大的龙? 例如
module ReusableModule
def module_method
puts "Module Method: Hi there!"
end
end
class ClassThatIncludes
include ReusableModule
end
class ClassThatExtends
extend ReusableModule
end
puts "Include"
ClassThatIncludes.new.module_method # "Module Method: Hi there!"
puts "Extend"
ClassThatExtends.module_method # "Module Method: Hi there!"
Run Code Online (Sandbox Code Playgroud)
Joh*_*hat 310
extend - 将指定模块的方法和常量添加到目标的元类(即单例类),例如
Klazz.extend(Mod)
,现在Klazz有Mod的方法(作为类方法)obj.extend(Mod)
,现在obj有Mod的方法(作为实例方法),但没有其他实例obj.class
添加了这些方法.extend
是一种公共方法include - 默认情况下,它将指定模块的方法混合为目标模块/类中的实例方法.例如
class Klazz; include Mod; end;
,现在Klazz的所有实例都可以访问Mod的方法(作为实例方法)include
是一个私有方法,因为它旨在从容器类/模块中调用.但是,模块经常通过修补方法来覆盖其 include
行为included
.这在传统的Rails代码中非常突出.来自Yehuda Katz的更多细节.
include
假设您运行以下代码,有关其默认行为的更多详细信息
class Klazz
include Mod
end
Run Code Online (Sandbox Code Playgroud)
@@foo
或@@bar
super
Klazz #foo将在检查之前检查Mod#foo Klazz的真正超类的foo方法.有关详细信息,请参阅RubySpec.).当然,ruby核心文档总是最适合这些事情的地方.RubySpec项目也是一个很棒的资源,因为他们精确地记录了这些功能.
#include
RubySpec rubydoc#included
RubySpec rubydoc#extend
RubySpec rubydoc#extended
RubySpec rubydoc#extend_object
RubySpec rubydoc#append_features
RubySpec rubydoc dom*_*ell 240
你所说的是对的.然而,除此之外还有更多.
如果你有一个类Klazz
和模块Mod
,包括Mod
in Klazz
给出了Klazz
访问Mod
方法的实例.或者你可以Klazz
通过Mod
赋予类 Klazz
访问Mod
方法来扩展.但是你也可以扩展一个任意对象o.extend Mod
.在这种情况下,单个对象获取Mod
方法,即使具有相同类的所有其他对象o
也没有.
Tob*_*ede 14
那是对的.
在幕后,include实际上是append_features的别名,(来自文档):
Ruby的默认实现是将此模块的常量,方法和模块变量添加到aModule(如果此模块尚未添加到aModule或其祖先之一).
当您将include
一个模块放入一个类中时,模块方法将作为实例方法导入。
但是,当您extend
将模块放入类时,模块方法将作为类方法导入。
例如,如果我们有一个Module_test
定义如下的模块:
module Module_test
def func
puts "M - in module"
end
end
Run Code Online (Sandbox Code Playgroud)
现在,对于include
模块。如果我们定义类A
如下:
class A
include Module_test
end
a = A.new
a.func
Run Code Online (Sandbox Code Playgroud)
输出将是:M - in module
。
如果我们更换线include Module_test
与extend Module_test
并再次运行该代码,我们收到以下错误:undefined method 'func' for #<A:instance_num> (NoMethodError)
。
将方法调用更改a.func
为A.func
,输出更改为:M - in module
。
从上面的代码执行可以看出,当我们include
是一个模块时,它的方法就变成了实例方法,当我们extend
成为一个模块时,它的方法就变成了类方法。
归档时间: |
|
查看次数: |
79321 次 |
最近记录: |