Mam kilka modułów, w których chciałbym użyć zmiennych instancji. Obecnie inicjuję je w ten sposób:
module MyModule
def self.method_a(param)
@var ||= 0
# other logic goes here
end
end
Mógłbym również wywołać metodę init, aby je zainicjować:
def init
@var = 0
end
ale to oznaczałoby, że muszę pamiętać, aby zawsze to nazywać.
Czy jest lepszy sposób na zrobienie tego?
Odpowiedzi:
Zainicjuj je w definicji modułu.
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!"
Spowoduje to ustawienie zmiennych instancji, gdy moduł jest zdefiniowany. Pamiętaj, że możesz później ponownie otworzyć moduł, aby dodać więcej zmiennych instancji i definicji metod lub przedefiniować istniejące:
# 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?"
źródło
Możesz użyć:
def init(var=0) @var = var end
I domyślnie będzie to 0, jeśli nic nie przekażesz.
Jeśli nie chcesz za każdym razem dzwonić, możesz użyć czegoś takiego:
module AppConfiguration mattr_accessor :google_api_key self.google_api_key = "123456789" ... end
źródło
dla klasy, powiedziałbym, co następuje, ponieważ inicjalizacja jest wywoływana za każdym razem, gdy .new jest nową instancją klasy.
def initialize @var = 0 end
z Practical Ruby :
źródło
Odpowiedziałem podobną pytanie , można ustawić zmienne instancji klasy w ten sposób
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"
źródło
Najwyraźniej inicjowanie zmiennych instancji w module w Rubim jest złą formą. (Z powodów, których w pełni nie rozumiem, ale dotyczą kolejności, w jakiej tworzone są elementy).
Wydaje się, że najlepszą praktyką jest używanie akcesorów z leniwą inicjalizacją, na przykład:
module MyModule def var @var ||= 0 end end
Następnie użyj
var
jako gettera dla@var
.źródło
nil
orfalse