83

我有一些模块,我想在其中使用实例变量。我目前正在像这样初始化它们:

module MyModule
  def self.method_a(param)
    @var ||= 0
    # other logic goes here
  end
end

我也可以调用一个 init 方法来初始化它们:

def init
  @var = 0
end

但这意味着我必须记住始终调用它。

有没有更好的方法来做到这一点?

4

5 回答 5

112

在模块定义中初始化它们。

module MyModule
  # self here is MyModule
  @species = "frog"
  @color = "red polka-dotted"
  @log = []

  def self.log(msg)
    # self here is still MyModule, so the instance variables are still available
    @log << msg
  end
  def self.show_log
    puts @log.map { |m| "A #@color #@species says #{m.inspect}" }
  end
end

MyModule.log "I like cheese."
MyModule.log "There's no mop!"
MyModule.show_log #=> A red polka-dotted frog says "I like cheese."
                  #   A red polka-dotted frog says "There's no mop!"

这将在定义模块时设置实例变量。请记住,您可以稍后重新打开模块以添加更多实例变量和方法定义,或重新定义现有的:

# continued from above...
module MyModule
  @verb = "shouts"
  def self.show_log
    puts @log.map { |m| "A #@color #@species #@verb #{m.inspect}" }
  end
end
MyModule.log "What's going on?"
MyModule.show_log #=> A red polka-dotted frog shouts "I like cheese."
                  #   A red polka-dotted frog shouts "There's no mop!"
                  #   A red polka-dotted frog shouts "What's going on?"
于 2009-03-30T19:42:45.903 回答
5

您可以使用:

def init(var=0)
 @var = var
end

如果您不传递任何内容,它将默认为 0。

如果你不想每次都调用它,你可以使用这样的东西:

module AppConfiguration
   mattr_accessor :google_api_key
   self.google_api_key = "123456789"
...

end
于 2009-03-30T18:03:15.470 回答
2

我回答了一个类似的问题,你可以设置类实例变量这样做

module MyModule
  class << self; attr_accessor :var; end
end

MyModule.var
=> nil

MyModule.var = 'this is saved at @var'
=> "this is saved at @var"

MyModule.var    
=> "this is saved at @var"
于 2012-01-09T05:13:24.093 回答
2

显然,在 Ruby 的模块中初始化实例变量是一种不好的形式。(出于我不完全理解的原因,但与实例化事物的顺序有关。)

似乎最佳实践是使用具有延迟初始化的访问器,如下所示:

module MyModule
  def var
    @var ||= 0 
  end
end

然后var用作@var.

于 2014-04-15T12:14:19.813 回答
1

对于一个类,我会说以下内容,因为每当您 .new 类的新实例时都会调用初始化。

def initialize
   @var = 0
end

来自实用红宝石

它继续说,如果包含类的初始化调用 super,则将调用模块的初始化,但没有提到这是 super 如何在任何地方工作的结果,而不是对初始化的特殊处理。(为什么有人会假设 initialize 得到特殊处理?因为它在可见性方面得到了特殊处理。特殊情况会造成混乱。)

于 2009-03-30T18:12:28.087 回答