Pertanyaan Bagaimana saya bisa menginisialisasi variabel instan sebuah modul di Ruby?


Saya memiliki beberapa modul di mana saya ingin menggunakan variabel instan. Saya sedang menginisialisasi mereka seperti ini:

module MyModule
  def self.method_a(param)
    @var ||= 0
    # other logic goes here
  end
end

Saya juga bisa memanggil metode init untuk menginisialisasi mereka:

def init
  @var = 0
end

tetapi ini berarti saya harus ingat untuk selalu menyebutnya.

Apakah ada cara yang lebih baik untuk melakukan ini?


75
2018-03-30 17:56


asal


Jawaban:


Inisialisasi mereka dalam definisi modul.

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!"

Ini akan mengatur variabel instan ketika modul didefinisikan. Ingat, Anda dapat alwasys membuka kembali modul nanti untuk menambahkan lebih banyak variabel instan dan definisi metode, atau untuk mendefinisikan ulang yang sudah ada:

# 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?"

101
2018-03-30 19:42



Kamu dapat memakai:

def init(var=0)
 @var = var
end

Dan itu akan menjadi 0 jika Anda tidak melewatkan apa pun.

Jika Anda tidak ingin memanggilnya setiap kali, Anda dapat menggunakan sesuatu seperti ini:

module AppConfiguration
   mattr_accessor :google_api_key
   self.google_api_key = "123456789"
...

end

6
2018-03-30 18:03



untuk kelas, saya akan mengatakan yang berikut, karena inisialisasi dipanggil setiap kali Anda. baru contoh baru dari kelas.

def initialize
   @var = 0
end

dari Ruby Praktis:

Ini melanjutkan dengan mengatakan bahwa modul itu   menginisialisasi akan dipanggil jika sebuah   termasuk panggilan inisialisasi kelas   super, tetapi tidak menyebutkan bahwa ini   adalah konsekuensi dari cara kerja super   di mana-mana, bukan penanganan khusus untuk   menginisialisasi. (Mengapa mungkin seseorang berasumsi   menginisialisasi mendapat penanganan khusus?   Karena itu mendapat penanganan khusus dengan   menghormati visibilitas. Kasus-kasus khusus   buat kebingungan.)


2
2018-03-30 18:12



Rupanya itu bentuk buruk untuk menginisialisasi variabel instan dalam modul di Ruby. (Untuk alasan yang saya tidak sepenuhnya mengerti, tetapi berkaitan dengan urutan di mana hal-hal yang dipakai.)

Tampaknya praktik terbaik adalah menggunakan accessor dengan inisialisasi malas, seperti:

module MyModule
  def var
    @var ||= 0 
  end
end

Kemudian gunakan var sebagai rajanya @var.


2
2018-04-15 12:14



saya menjawab serupa pertanyaan, Anda dapat mengatur variabel instan kelas melakukan ini

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"

1
2018-01-09 05:13