Как инициализировать переменные экземпляра модуля в Ruby?
У меня есть некоторые модули, в которых я бы хотел использовать переменные экземпляра. В настоящее время я инициализирую их следующим образом:
module MyModule
def self.method_a(param)
@var ||= 0
# other logic goes here
end
end
Я также мог бы вызвать метод init для их инициализации:
def init
@var = 0
end
но это будет означать, что я должен помнить, чтобы всегда называть его.
Есть ли лучший способ сделать это?
Ответы
Ответ 1
Инициализировать их в определении модуля.
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 no mop!"
MyModule.show_log #=> A red polka-dotted frog says "I like cheese."
# A red polka-dotted frog says "There 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 going on?"
MyModule.show_log #=> A red polka-dotted frog shouts "I like cheese."
# A red polka-dotted frog shouts "There no mop!"
# A red polka-dotted frog shouts "What going on?"
Ответ 2
Вы можете использовать:
def init(var=0)
@var = var
end
И по умолчанию будет 0, если вы ничего не передадите.
Если вы не хотите называть его каждый раз, вы можете использовать что-то вроде этого:
module AppConfiguration
mattr_accessor :google_api_key
self.google_api_key = "123456789"
...
end
Ответ 3
для класса, я бы сказал следующее, поскольку инициализация вызывается всякий раз, когда вы .new новый экземпляр класса.
def initialize
@var = 0
end
from Практический рубин:
Далее говорится, что модуль инициализация будет вызываться, если включая вызовы инициализации класса супер, но не упоминает, что это является следствием того, как супер работает везде, а не инициализации. (Почему можно предположить Инициализация получает специальную обработку? Потому что он получает специальную в отношении видимости. Особые случаи создать путаницу.)
Ответ 4
По-видимому, это плохая форма для инициализации переменных экземпляра в модуле в Ruby. (По причинам, которые я не совсем понимаю, но относится к порядку, в котором создаются вещи.)
Кажется, что наилучшей практикой является использование аксессуаров с ленивой инициализацией, например:
module MyModule
def var
@var ||= 0
end
end
Затем используйте var
в качестве получателя для @var
.
Ответ 5
я ответил на аналогичный вопрос , вы можете установить переменные экземпляра класса, делая это
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"