我有一些模块,我想在其中使用实例变量。我目前正在初始化它们:
module MyModule
def self.method_a(param)
@var ||= 0
# other logic goes here
end
end
我也可以调用init方法来初始化它们:
def init
@var = 0
end
但这意味着我必须记住要经常打电话。
有更好的方法吗?
答案 0 :(得分:103)
在模块定义中初始化它们。
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?"
答案 1 :(得分:5)
您可以使用:
def init(var=0)
@var = var
end
如果你没有传递任何东西,它将默认为0.
如果您不想每次都打电话,可以使用以下内容:
module AppConfiguration
mattr_accessor :google_api_key
self.google_api_key = "123456789"
...
end
答案 2 :(得分:2)
对于一个类,我会说以下内容,因为每当你重新启动类的新实例时都会调用initialize。
def initialize
@var = 0
end
接着说是一个模块 如果是,则调用initialize 包括类的初始化调用 超级,但没有提到这一点 是超级工作的结果 无处不在,不是特别处理 初始化。 (为什么可以假设 初始化得到特殊处理? 因为它得到特殊处理 尊重可见度。特别案例 制造混乱。)
答案 3 :(得分:2)
我回答了类似的question,你可以设置类实例变量这样做
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"
答案 4 :(得分:2)
显然,在Ruby中初始化模块中的实例变量是不好的形式。 (由于我不完全理解的原因,但与实例化事物的顺序有关。)
似乎最佳做法是使用具有延迟初始化的访问器,如下所示:
module MyModule
def var
@var ||= 0
end
end
然后使用var
作为@var
的获取者。