Buat variabel modul di Ruby

111

Apakah ada cara untuk membuat variabel dalam modul di Ruby yang berperilaku mirip dengan variabel kelas? Yang saya maksud dengan ini adalah bahwa itu akan dapat diakses tanpa menginisialisasi contoh modul, tetapi dapat diubah (tidak seperti konstanta dalam modul).

Mark Szymanski
sumber

Jawaban:

158

Ruby secara native mendukung variabel kelas dalam modul, sehingga Anda dapat menggunakan variabel kelas secara langsung, dan bukan beberapa variabel proxy atau pseudo-class:

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"
ke inti
sumber
5
+1 Sebenarnya, saya berpikir bahwa istilah 'variabel kelas' itu menyesatkan. Kelas adalah kasus khusus dari modul, dan variabel kelas dapat ditentukan pada modul. Mereka harus disebut variabel modul.
sawa
3
@sawa: Ini agak menyesatkan, tapi itu apa yang menggunakan Ruby sendiri: defined?(@@foo) => "class variable".
Andrew Grimm
1
Atau bisa juga disebut bidang statis. Sepertinya itulah mereka.
Peter Ajtai
@coreyward Hei, salahku. Mengapa perlu dua variabel kelas '@@'? Bukankah itu dianggap bau kode, terutama jika kelas diperluas untuk menggunakan variabel kelas? Saya sedang menguji ini dan saya menyadari bahwa saya bisa mendapatkan hasil yang sama dari @variabel contoh tunggal . Apakah ada alasan khusus untuk menggunakan variabel kelas? Terima kasih balasannya.
fabbb
2
mengapa panggilan yang berbeda di akhir: T.getdan T::get?
intrixius
31

Jika Anda tidak perlu memanggilnya dari dalam sebuah instance, Anda cukup menggunakan variabel instance di dalam badan modul.

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

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

Variabel instance @paramkemudian akan menjadi milik modul SomeModule, yang merupakan turunan Modulekelas.

sawa
sumber
23

Anda dapat menyetel variabel instance kelas dalam modul.

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

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

MyModule.var    
=> "this is saved at @var"
Orlando
sumber
+1, tetapi saya hanya akan menekankan bahwa variabel instance kelas berbeda dengan variabel kelas.
Andrew Grimm
4
ya benar-benar .. dan btw .. saya tidak merekomendasikan menggunakan variabel kelas sama sekali .. beberapa hal yang tidak terduga terjadi ketika Anda menggunakannya .. periksa artikel ini untuk melihat beberapa contoh oreillynet.com/ruby/blog/2007/01/…
Orlando
8

Anda juga dapat menginisialisasi nilai dalam definisi modul:

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

p MyModule.my_variable
Nakilon
sumber