Как инициализировать переменные экземпляра модуля в Ruby?
у меня есть некоторые модули, в которых я хотел бы использовать переменные экземпляра. В настоящее время я инициализирую их следующим образом:
module MyModule
def self.method_a(param)
@var ||= 0
# other logic goes here
end
end
Я также могу вызвать метод init для их инициализации:
def init
@var = 0
end
но это означало бы, что я должен помнить, чтобы всегда называть его.
есть ли лучший способ сделать это?
5 ответов
инициализировать их в определении модуля.
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!"
это установит переменные экземпляра, когда модуль будет определен. Помните, что вы можете alwasys повторно открыть модуль позже, чтобы добавить больше переменных экземпляра и определений методов, или переопределить существующие:
# 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
далее говорится, что модуль initialize будет вызываться, если включая вызовы initialize класса супер, но не упоминает, что это является следствием того, как работает супер везде, не специальный регулировать для инициализировать. (Почему можно предположить инициализировать получает особое обращение? Потому что он получает специальную обработку с уважение к видимости. Особый случай создавать путаницу.)
Я ответил похожим вопрос, вы можете установить переменные экземпляра класса этим
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"
по-видимому, инициализация переменных экземпляра в модуле в Ruby-плохая форма. (По причинам, которые я не совсем понимаю, но относящимся к порядку, в котором вещи создаются.)
кажется, что лучшей практикой является использование аксессоров с ленивой инициализацией, например:
module MyModule
def var
@var ||= 0
end
end
затем использовать var
как геттер для @var
.