Ruby:模块扩展/包括模块
我试图更好地理解模块是如何相互扩展和包含的 假设我有一个模块A:Ruby:模块扩展/包括模块,ruby,module,extend,Ruby,Module,Extend,我试图更好地理解模块是如何相互扩展和包含的 假设我有一个模块A: module A def learned_from_A true end end A.instance_methods # [:learned_from_A] module B extend A end B.learned_from_A # true 我把它的一袋把戏混合到B: module A def learned_from_A true end end A.instance_
module A
def learned_from_A
true
end
end
A.instance_methods # [:learned_from_A]
module B
extend A
end
B.learned_from_A # true
我把它的一袋把戏混合到B:
module A
def learned_from_A
true
end
end
A.instance_methods # [:learned_from_A]
module B
extend A
end
B.learned_from_A # true
我天真地试图给予C一切B都有:
module C
extend B
end
C.learned_from_A # NoMethodError
我想我已经对这件事了如指掌了。当B扩展A时,A的实例方法的副本通过B的singleton类绑定到B:
B.singleton_methods # [:learned_from_A]
虽然:从A中学习的\u可在B上调用,但它不是B的实例方法之一,因此当C扩展B时,从A中学习的\u不会复制到C
module C
extend B
end
C.singleton_methods # [:learned_from_A]
module B
include A
extend A
end
B.instance_methods # [:learned_from_A]
B.singleton_methods # [:learned_from_A]
module C
extend B
end
C.instance_methods # []
C.singleton_methods # [:learned_from_A]
如果B包含A,则A的实例方法的副本将包含在B自己的实例方法中
module B
include A
end
B.instance_methods # [:learned_from_A]
然后,C可以扩展B,B的所有实例方法(包括:从A中学习)都将被复制并绑定到C
module C
extend B
end
C.singleton_methods # [:learned_from_A]
module B
include A
extend A
end
B.instance_methods # [:learned_from_A]
B.singleton_methods # [:learned_from_A]
module C
extend B
end
C.instance_methods # []
C.singleton_methods # [:learned_from_A]
要使:B和C上都可以调用从A中学习到的内容,B可以扩展并包括A
module C
extend B
end
C.singleton_methods # [:learned_from_A]
module B
include A
extend A
end
B.instance_methods # [:learned_from_A]
B.singleton_methods # [:learned_from_A]
module C
extend B
end
C.instance_methods # []
C.singleton_methods # [:learned_from_A]
更现实地说,如果我希望A的方法可以在B上调用,并且B可以定义自己的另一个方法,并且能够将整个曲目混合到C,我不能这样做:
module B
extend A
include A
def self.buzz
true
end
end
module C
extend B
end
B只能共享其实例方法,不能共享其单例方法。因此,要使方法既可在B上调用,又可共享给其他对象,必须将其定义为实例方法并扩展到B本身:
module B
extend A
include A
extend self
def buzz
true
end
end
module C
extend B
end
在把这一切放在一起的过程中,有相当多的尝试和错误。这是一种准确的观察发生了什么的方式吗 我把它的一袋把戏混在一起 这个短语和你的问题让我相信在
包含
/扩展
的概念上有一点误解。我事先道歉,因为我不完全理解这个问题
例如,您有这样的模块:
module A
def a
puts "a"
end
def self.b
puts "b"
end
end
如您所见,有两种类型的方法:
- 单例法
- 实例_方法
A.singleton_methods
=> [:b]
A.instance_methods
=> [:a]
A.a
NoMethodError: undefined method `a' for A:Module
A.b
b
=> nil
如果您简单地包含一个
,则将其实例方法添加到当前模块实例方法中。当您简单地扩展一个时,您将把它的实例方法添加到当前模块的单例方法中
module B
include A
end
module C
extend A
end
B.instance_methods
=> [:a]
B.singleton_methods
=> []
C.instance_methods
=> []
C.singleton_methods
=> [:a]
还有一件事要说,您可以扩展self
,但不能包含self
,因为这没有任何意义,也会引发异常
module D
extend self
def a
puts "a"
end
def self.b
puts "b"
end
end
D.singleton_methods
=> [:b, :a]
D.instance_methods
=> [:a]
D.a
a #no error there because we have such singleton method
=> nil
我想这些东西可以帮助你。关于StackOverflow()的
extend
/include
有很多问题,您可以检查一下()。至少对于a
到B
到C
module A
def learned_from_A
true
end
end
module B
prepend A
end
B.learned_from_A # true
module C
extend B
end
C.learned_from_A # true
有没有办法简化你的问题?即使你把它放在一个要点中,并调试出不同的场景。我认为当你在B中扩展a时,你可能会混淆self的范围变化,然后期望C将有a。你改变范围。还可以调用#prepend。若要查看这些作用域如何变化,请在类上调用$祖先方法。听起来您想用相同的名称调用mom和children:PGood answer!我想有一点不小心被调换了。上面的一句话应该是:“当你简单地扩展一个时,你就是在把它的实例方法添加到当前的模块单例方法中。”(答案中的“实例”和“单例”是互换的)