Створення змінних модулів у Ruby


111

Чи є якийсь спосіб створити змінну в модулі в Ruby, яка б поводилася аналогічно змінній класу? Що я маю на увазі під цим, це те, що до нього можна отримати доступ без ініціалізації екземпляра модуля, але він може бути змінений (на відміну від констант в модулях).

Відповіді:


158

Ruby в основному підтримує змінні класу в модулях, тому ви можете використовувати змінні класу безпосередньо, а не деякі проксі або псевдокласові змінні:

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 Насправді я думав, що термін "класова змінна" вводить в оману. Класи - це особливі випадки модулів, а змінні класу визначаються на модулях. Їх слід називати модульними змінними.
sawa

3
@sawa: Це кілька вводить в оману, але це те , що використовує сам Ruby: defined?(@@foo) => "class variable".
Ендрю Грімм

1
Або їх можна назвати статичними полями. Здається, що вони є.
Пітер Айтай

@coreyward Привіт моя помилка. Чому необхідність у двох змінних класу '@@'? Чи не вважається це кодовим запахом, особливо якщо клас розширений для використання змінних класу? Я тестував це і зрозумів, що можу отримати той самий результат від однієї @змінної екземпляра. Чи є конкретна причина використання змінних класу? Дякую за відповідь.
fabbb

2
чому в кінці різні дзвінки: T.getі T::get?
інтрикс

31

Якщо вам не потрібно викликати його всередині екземпляра, ви можете просто використовувати змінну екземпляра в корпусі модуля.

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

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

Потім змінна інстанція @paramбуде належати модулю SomeModule, який є екземпляром Moduleкласу.


23

Ви можете встановити змінну примірника класу в модулі.

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

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

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

+1, але я лише наголошу, що змінні екземплярів класу відрізняються від змінних класів.
Ендрю Грімм

4
так, повністю .. і btw .. я не рекомендую взагалі використовувати змінні класу .. деякі несподівані речі трапляються, коли ви їх використовуєте .. перегляньте цю статтю, щоб побачити приклади oreillynet.com/ruby/blog/2007/01/…
Orlando

8

Ви також можете ініціалізувати значення в межах визначення модуля:

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

p MyModule.my_variable
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.