我试图更好地了解模块如何扩展并相互包含。
说我有模块 A :
module A
def learned_from_A
true
end
end
A.instance_methods # [:learned_from_A]
我把它的技巧混合到 B :
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&#39>的实例方法的副本将通过B&#39的单例类绑定到 B :
B.singleton_methods # [:learned_from_A]
虽然:learned_from_A 可在 B 上调用,但它不是 B 的实例之一方法,因此当 C 扩展 B 时,:learned_from_A 不被复制到 C
如果 B 而包含 A ,A&#39>的实例方法的副本将包含在B&#中39;自己的实例方法。
module B
include A
end
B.instance_methods # [:learned_from_A]
然后, C 可以扩展 B ,并且所有B的实例方法(包括:learned_from_A )都将被复制并且绑定到 C 。
module C
extend B
end
C.singleton_methods # [:learned_from_A]
要在 B 和 C , B 上调用:learned_from_A 可以扩展和包括 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 的方法,并且 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
将这些全部放在一起有相当多的反复试验。这是一种查看正在发生的事情的准确方法吗?
答案 0 :(得分:5)
我把它的伎俩混合到B
中
这句话和你的问题一般让我相信include
/ extend
事物的概念存在一些误解。我提前道歉,因为我不完全理解这个问题。
例如,你有这样的模块:
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
如果简单地include A
,则将实例方法添加到当前模块实例方法中。简单地执行extend A
时,您将实例方法添加到当前模块 singleton 方法中。
module B
include A
end
module C
extend A
end
B.instance_methods
=> [:a]
B.singleton_methods
=> []
C.instance_methods
=> []
C.singleton_methods
=> [:a]
还有一件事要说,你可以extend self
而不是include 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
我猜这些东西可以帮到你。您可以检查(example)StackOverflow上有很多关于extend
/ include
的问题。
答案 1 :(得分:0)
以下内容似乎至少对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