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或@@barsuperKlazz #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,包括Modin 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 次 |
| 最近记录: |