2009-03-30 16 views
72

Ben örnek değişkenlerden kullanmak istiyorum nereye bazı modüllere sahip Şu anda bu gibi onları başlatılıyor ediyorum:Bir modülün örnek değişkenlerini Ruby'de nasıl ilklendirebilirim? .

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

Ben de onları başlatmak için bir init yöntemini diyebiliriz:

def init 
    @var = 0 
end 

ama bu her zaman onu aramak için hatırlamak zorunda olduğu anlamına gelir.

Bunu yapmanın daha iyi bir yolu var mı?

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

Ve sen bir şey geçemiyor eğer 0 öntanımlıdır:

+3

İlk kod bloğu, bir modül örneği var (MyModule'nin tip nesnesinin kapsamındaki bir var) değil, ikinci bir "düz" örnek var (bir örnek kapsamındaki bir var modülü)? Bence bu iki kod bloğu aynı şeyi yapmıyor ... –

cevap

98

modül tanımında onları başlatın.

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

Bu, modül tanımlandığında örnek değişkenleri ayarlayacaktır.

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

Birisi dokunaklı rehberi okuyor;) –

+12

Biraz zaman oldu, ama evet :). Ayrıca, Messrs Foo ve Bar hakkında söylenmesi gereken her şeyin söylendiğini hissediyorum. – rampion

+0

Cevabınız için teşekkür ederiz. – Geo

6

kullanabilirsiniz. initialize aldığınızda sizi denir beri, aşağıdakileri derdim bir sınıf için

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

end 
+0

Yani, bu fonksiyonu modüle bir şey yapmadan önce çağırmam gerekecek mi? – Geo

+0

Bu sorunu önlemek için ikinci bir yol ekledim - raylar kodundan – Brian

2

: Eğer her onu aramak zorunda istemiyorsanız

, böyle bir şey kullanabilirsiniz. sınıfın yeni bir örneğini yeni. Practical Ruby den

def initialize 
    @var = 0 
end 

:

O sınıfının initialize içeren bir süper çağırırsa bir modülün initialize denen olacağını söylemeye devam ediyor, ancak bu bir sonucudur söz etmez süper her yerde her yerde çalışır, için özel işlem başlatılmaz. (Neden kimse initialize özel işlem alır üstlenebilir? o görünürlüğe bakımından özel işlem alır çünkü. Özel durumlarda karışıklık yaratmak.)

+1

Bir modül, başlangıç ​​olarak başlatılacak mı? İlk cevabım buydu. Aranmamasını açıklamak için ikincisini ekledim. – Brian

+1

OP özel olarak belirtilen modüller, sınıflar değil – Zensaburou

1

i, bu

yapıyor sınıf örnek değişkenler ayarlayabilirsiniz benzer question cevap verdi: Eğer alwasys sonra daha örnek değişkenler ve yöntem tanımları eklemek veya mevcut olanları yeniden tanımlamak için modül yeniden açabilirsiniz unutmayın
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" 
2

Görünüşe göre Ruby'deki bir modülde örnek değişkenlerini başlatmak kötü bir biçimdir. (Nedenlerle ben tam anlamıyorum, ama işler örneği sırayla ait.)

En iyi uygulama şöyle, tembel başlatma ile erişenleri kullanmak olduğunu görünüyor:

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

Sonra var'u @var için alıcı olarak kullanın.

+3

Not: Bu, @var ''nil' veya' false' ayarlanmasına asla izin vermeyecektir. – steel

İlgili konular