Utwórz zmienne modułu w Rubim


111

Czy istnieje sposób na utworzenie zmiennej w module w Rubim, która zachowywałaby się podobnie do zmiennej klasy? Rozumiem przez to, że byłby dostępny bez inicjowania instancji modułu, ale można go zmienić (w przeciwieństwie do stałych w modułach).

Odpowiedzi:


158

Ruby natywnie obsługuje zmienne klas w modułach, więc możesz używać zmiennych klas bezpośrednio, a nie niektórych zmiennych proxy lub pseudoklas:

module Site
  @@name = "StackOverflow"

  def self.setName(value)
    @@name = value
  end

  def self.name
    @@name
  end
end

Site.name            # => "StackOverflow"
Site.setName("Test")
Site.name            # => "Test"

5
+1 Właściwie to myślałem, że termin „zmienna klasy” jest mylący. Klasy są specjalnymi przypadkami modułów, a zmienne klas można definiować w modułach. Powinny nazywać się zmiennymi modułowymi.
sawa

3
@sawa: To jest trochę mylący, ale to, co sama Ruby używa: defined?(@@foo) => "class variable".
Andrew Grimm,

1
Lub można je nazwać polami statycznymi. Wydaje się, że tym właśnie są.
Peter Ajtai

@coreyward Hej, mój błąd. Dlaczego potrzebne są dwie zmienne klasy „@@”? Czy nie jest to uważane za zapach kodu, zwłaszcza jeśli klasa jest rozszerzona o zmienne klasowe? Testowałem to i zdałem sobie sprawę, że mogę uzyskać ten sam wynik z jednej @zmiennej instancji. Czy istnieje konkretny powód używania zmiennych klas? Dziękuję za odpowiedź.
fabbb

2
dlaczego różne wezwania na końcu: T.geti T::get?
intrixius,

31

Jeśli nie musisz wywoływać go z poziomu instancji, możesz po prostu użyć zmiennej instancji w treści modułu.

module SomeModule
  module_function
  def param; @param end
  def param= v; @param = v end
end

SomeModule.param
# => nil
SomeModule.param = 1
SomeModule.param
# => 1

Zmienna instancji @parambędzie wtedy należeć do modułu SomeModule, który jest instancją Moduleklasy.


23

w module można ustawić zmienną instancji klasy.

module MyModule
   class << self; attr_accessor :var; end
end

MyModule.var = 'this is saved at @var'

MyModule.var    
=> "this is saved at @var"

+1, ale podkreślę tylko, że zmienne instancji klas różnią się od zmiennych klas.
Andrew Grimm,

4
tak, całkowicie .. i przy okazji ... nie polecam w ogóle używania zmiennych klas .. niektóre nieoczekiwane rzeczy dzieją się, gdy ich używasz .. sprawdź ten artykuł, aby zobaczyć kilka przykładów oreillynet.com/ruby/blog/2007/01/ ...
Orlando

8

Możesz także zainicjować wartość w ramach definicji modułu:

module MyModule
  class << self
    attr_accessor :my_variable
  end
  self.my_variable = 2 + 2
end

p MyModule.my_variable
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.