gpt4 book ai didi

Ruby:扩展/包含模块的模块

转载 作者:数据小太阳 更新时间:2023-10-29 06:39:40 25 4
gpt4 key购买 nike

我正在努力更好地理解模块如何相互扩展和包含。

假设我有模块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 的实例方法的副本通过 B 的单例类绑定(bind)到 B:

B.singleton_methods  # [:learned_from_A]

虽然 :learned_from_A 可在 B 上调用,但它不是 B实例方法之一,因此当 C 扩展 B 时,:learned_from_A 不会复制到 C


如果 B 包含 A,A 的实例方法的副本将包含在 B 自己的实例方法中。

module B
include A
end

B.instance_methods # [:learned_from_A]

然后,C 可以扩展 B,B 的所有实例方法(包括 :learned_from_A)将被复制并绑定(bind)到 >C.

module C
extend B
end

C.singleton_methods # [:learned_from_A]

要使 :learned_from_A 可在 B C 上调用,B可以扩展包括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

将所有这些放在一起需要进行大量的试验和错误。这是查看正在发生的事情的准确方法吗?

最佳答案

I mix its bag of tricks into B

这句话和你的问题一般让我相信在 include/extend 的概念上存在一点误解。我提前道歉,因为我不完全理解这个问题。

例如你有这样的模块:

module A
def a
puts "a"
end

def self.b
puts "b"
end
end

如您所见,有两种类型的方法:

  • singleton_methods
  • 实例方法

这是证明它们实际上不同的最简单方法:

A.singleton_methods
=> [:b]
A.instance_methods
=> [:a]
A.a
NoMethodError: undefined method `a' for A:Module
A.b
b
=> nil

如果您简单地include A,您就是将它的instance 方法添加到当前模块的instance 方法中。当您简单地extend A 时,您是在将其instance 方法添加到当前模块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

我想这些东西可以帮助你。 StackOverflow 上有很多关于extend/include 的问题,您可以查看 (example)。

关于Ruby:扩展/包含模块的模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33848651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com