即使我无法创建模块的实例,我怎么可能在模块中拥有实例变量?@stack
下面的模块的目的是Stacklike
什么?
module Stacklike
def stack
@stack ||= []
end
end
将实例变量想象成任何包含您的模块的类中都会存在的东西,事情就更有意义了:
module Stacklike
def stack
@stack ||= []
end
def add_to_stack(obj)
stack.push(obj)
end
def take_from_stack
stack.pop
end
end
class ClownStack
include Stacklike
def size
@stack.length
end
end
cs = ClownStack.new
cs.add_to_stack(1)
puts cs.size
将输出“1”
见下文:
p RUBY_VERSION
module Stacklike
def stack
@stack ||= []
end
def add_to_stack(obj)
stack.push(obj)
end
def take_from_stack
stack.pop
end
end
class A
include Stacklike
end
a = A.new
p a.instance_variables #<~~ E
p a.instance_variable_defined?(:@stack) #<~~ A
a.add_to_stack(10) #<~~ B
p a.instance_variable_defined?(:@stack) #<~~ C
p a.instance_variables #<~~ D
输出:
"1.9.3"
[]
false
true
[:@stack]
解释:是的,Module
实例变量存在于类中class
。include
但是您可以看到它p a.instance_variable_defined?(:@stack)
显示false
为直到A@stack
仍未定义。在B点,我定义了实例变量@stack。因此C点中的语句输出为。意味着模块实例变量不是由模块本身创建的,但如果包含该模块,则可以由实例完成。E中的语句仍输出为未定义实例变量的那一点,但是如果您看到D行的输出,则证明true
class
class
[]
@stack
在 的对象a
内class A
。
为什么会有这样的设计?
这是设计或有时来自要求。假设您被要求编写一个堆栈操作代码,将被两家订票公司使用,SayA
和B
。现在A
是为他们的客户服务的堆栈政策,但他们也有更多的手续。B
公司也使用堆栈策略与他们自己的手续不同A
。因此,如果在内部设计操作Stack
,最好将其写在一个共同的地方,就像两者一样,并且在它们内部具有共同的功能。将来,如果另一家公司来找您,您也可以将该模块用于他们的课程,而无需为每个 重写相同的功能,并且class A
class B
A
B
C
A
B
C
. 可以有更多的想法,但希望这会帮助你回答你自己的最后一部分问题。
这就是概念。希望能帮助到你。
干杯!!
当您在一个类中包含一个模块时,它的所有实例方法都会有效地“粘贴”到宿主类中。因此,如果您有:
class Lifo
include Stacklike
end
l = Lifo.new
l.add_to_stack(:widget)
然后l
现在有一个实例变量@stack
,从Stacklike
.
当您在某个其他类中包含模块 Stacklike 时,该实例变量将可用,就好像它是在该类中定义的一样。这使您可以选择从模块本身设置和处理基类的实例变量。