为什么下面的代码会返回NoMethodFound
错误:
module Mod1
def print_string
puts 'hello ruby'
end
end
module Mod2
include Mod1
end
Mod2.print_string
虽然下面的代码运行正常吗?
module Mod1
def print_string
puts 'hello ruby'
end
end
module Mod2
extend Mod1
end
Mod2.print_string
答案 0 :(得分:1)
extend - 将指定模块的方法和常量添加到目标的元类(即单例类) 例如
Klazz.extend(Mod)
,现在Klazz有Mod的方法(作为课程方法)obj.extend(Mod)
,现在obj有Mod的方法(作为实例方法),但obj.class
的其他实例都没有这些方法。extend
是一种公共方法include - 默认情况下,它将指定模块的方法混合为目标模块/类中的实例方法。 e.g。
class Klazz; include Mod; end;
,现在Klazz的所有实例都可以访问Mod的方法(作为实例方法)include
是一种私有方法,因为它旨在从容器类/模块中调用。 然而,模块经常通过猴子修补include
方法覆盖 included
的行为。这在传统的Rails代码中非常突出。 more details from Yehuda Katz。
有关include
及其默认行为的详细信息,假设您运行以下代码
class Klazz
include Mod
end
@@foo
或@@bar
super
在Klazz中,#foo会在检查Klazz的真正超类foo方法之前检查Mod#foo。有关详细信息,请参阅RubySpec。)。当然,the ruby core documentation总是最适合这些事情的地方。 The RubySpec project也是一个很棒的资源,因为它们准确地记录了这些功能。
参考:John
答案 1 :(得分:0)
是的,extend
将模块的方法作为类方法添加到调用者,而include
将它们添加为实例方法。
一个例子(使用类而不是模块,因为模块不能有实例......)
这有效......
module Mod1
def print_string
puts 'hello ruby'
end
end
class Mod2
extend Mod1
end
Mod2.print_string
这有效......
module Mod1
def print_string
puts 'hello ruby'
end
end
class Mod2
include Mod1
end
mod_instance = Mod2.new
mod_instance.print_string