我如何在Ruby中初始化模块的实例variables?
我有一些模块,我想在其中使用实例variables。我目前正在初始化他们像这样:
module MyModule def self.method_a(param) @var ||= 0 # other logic goes here end end
我也可以调用init方法来初始化它们:
def init @var = 0 end
但是这意味着我必须记得总是叫它。
有没有更好的方法来做到这一点?
在模块定义中初始化它们。
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!"
这将在模块定义时设置实例variables。 请记住,您可以稍后重新打开该模块以添加更多实例variables和方法定义,或重新定义现有的模块:
# 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?"
您可以使用:
def init(var=0) @var = var end
如果你不通过任何事情,它将默认为0。
如果你不想每次都调用它,你可以使用这样的东西:
module AppConfiguration mattr_accessor :google_api_key self.google_api_key = "123456789" ... end
对于一个类,我会说下面的,因为初始化被称为每当你新。类的一个新的实例。
def initialize @var = 0 end
从实用ruby :
它继续说,如果一个包含类的初始化调用超级,那么将调用一个模块的初始化,但是并没有提到这是由于超级工作到处,而不是特殊的初始化处理的结果。 (为什么会假设初始化得到特殊的处理呢?因为它在可见性方面得到了特殊的处理,特殊情况会造成混乱。)
显然,在Ruby中,在模块中初始化实例variables是一种糟糕的forms。 (由于我不完全理解的原因,但是涉及到实例化的顺序)。
看来最好的做法是使用懒惰初始化访问器,如下所示:
module MyModule def var @var ||= 0 end end
然后使用var
作为@var
的getter。
我回答了类似的问题 ,你可以设置类实例variables做这个
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"