ruby 模块中的示例变量?

goqiplq2  于 2022-12-18  发布在  Ruby
关注(0)|答案(5)|浏览(174)

我怎么可能在一个模块中拥有示例变量,即使我不能创建模块的示例?下面模块Stacklike@stack的用途是什么?

module Stacklike
  def stack
    @stack ||= []
  end
end
8zzbczxx

8zzbczxx1#

把示例变量看作是存在于包含模块的任何类中的东西,这样就更有意义了:

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”

ybzsozfc

ybzsozfc2#

参见以下内容:

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的输出,则证明@stack位于class A的对象a内部。
为何如此设计

这是设计或者有时来自需求。假设你被要求写一个栈操作代码,将被两家机票预订公司使用,比如说AB。现在A是他们的客户要服务的堆栈策略,但他们也有更多的形式。B公司也使用堆栈策略,有自己的形式,与A不同。因此,在class Aclass B内部设计Stack操作时,最好将其写在公共位置。因为AB都有相同的功能。将来如果另一个公司C找你,你也可以在他们的类中使用那个模块,而不用为每个A重写相同的功能。BC。可以有更多的想法,但希望这将帮助你回答你自己的最后一部分问题。
这就是所有的概念。希望它能有所帮助。
干杯!

mkh04yzy

mkh04yzy3#

当你在一个类中包含一个模块时,它的所有示例方法都被有效地“粘贴”到宿主类中。

class Lifo
  include Stacklike
end

l = Lifo.new
l.add_to_stack(:widget)

然后l现在有了一个示例变量@stack,它是从Stacklike引入的。

hc2pp10m

hc2pp10m4#

当你把模块Stacklike包含在其他类中时,示例变量就像是在那个类中定义的一样,这样你就可以选择从模块本身设置和处理基类的示例变量。

wswtfjt7

wswtfjt75#

请注意,模块可以存储自己的示例变量,而不管它是否包含在类中。
考虑:

module Stacklike
  def self.stack(args = nil)
    @stack ||= (args)
  end
end

Stacklike.instance_variables
> []

Stacklike.stack("original stack")
> "original stack"

Stacklike.instance_variables
> [:@stack]

Stacklike.stack("new stack")
> "original stack"

当你定义模块StackLike时,这创建了一个名为StackLike的对象,它的类型为Class,因为它是一个对象,所以它可以有自己的示例变量,这些变量可以通过它的类方法访问。

相关问题