即使我无法创建模块的实例,我怎么可能在模块中有实例变量?下面的模块@stack
中Stacklike
的目的是什么?
module Stacklike
def stack
@stack ||= []
end
end
答案 0 :(得分:43)
将实例变量视为包含模块的任何类中存在的东西,事情更有意义:
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”
答案 1 :(得分:13)
见下文:
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
,@stack
仍未定义,直到 A 。在 B 点,我定义了实例变量@stack。因此,语句 C ,输出为true
。表示模块实例变量不是由模块本身创建的,但如果class
包含该模块,则可以由class
实例完成。 E 输出[]
中的语句仍然没有定义实例变量,但如果您看到 D 行的输出,则证明{ {1}}位于@stack
的对象a
内。
为何选择此类设计?
这是设计或有时来自要求。假设您被要求编写一个堆栈操作代码,将由两个预订公司使用,说class A
和A
。现在B
是他们的客户服务的堆栈政策,但他们还有更多的手续。 A
公司也使用堆栈策略,其自己的手续与B
不同。因此,如果在A
和Stack
内设计class A
操作,最好将其写在一个公共位置,因为class B
和A
都具有此功能他们之间很常见。将来如果有另一家公司B
来到您这里,您也可以将该模块用于他们的课程,而无需为每个C
,A
和B
重写相同的功能。可以有更多的想法,但希望这将有助于你回答你自己的最后一部分问题。
这就是概念。希望它有所帮助。
干杯!!
答案 2 :(得分:5)
当您在类中包含模块时,其所有实例方法都会有效地“粘贴”到主机类中。所以如果你有:
class Lifo
include Stacklike
end
l = Lifo.new
l.add_to_stack(:widget)
然后l
现在有一个实例变量@stack
,从Stacklike
引入。
答案 3 :(得分:3)
当您在其他类中包含模块Stacklike时,实例变量将可用,就好像它是在该类中定义的那样。这使您可以选择从模块本身设置和处理基类的实例变量。