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