Adı verilen bir örnek değişkeninin değerini alın


99

Genel olarak, ismine bir dizede sahip olduğum bir nesneye nasıl referans alabilirim?

Daha spesifik olarak, parametre adlarının bir listesine sahibim (üye değişkenler - dinamik olarak oluşturulmuş, böylece onlara doğrudan başvuramıyorum).

Her parametre, aynı zamanda bir from_smetodu olan bir nesnedir .

Aşağıdakine benzer bir şey yapmak istiyorum (ki bu işe yaramıyor ...)

define_method(:from_s) do | arg |
    @ordered_parameter_names.each do | param |
        instance_eval "field_ref = @#{param}"
        field_ref.from_s(param)
    end
end

Yanıtlar:


179

Bunu başarmanın en deyimsel yolu şudur:

some_object.instance_variable_get("@#{name}")

+Veya kullanmaya gerek yoktur intern; Ruby bunu iyi halledecek. Bununla birlikte, kendinizi başka bir nesneye uzanıp yumurtalıklarını çekerken bulursanız, kapsüllemeyi kırmış olma ihtimaliniz oldukça yüksektir.

Bir ivar'a açıkça erişmek istiyorsanız, yapılacak doğru şey onu bir erişimci yapmaktır. Aşağıdakileri göz önünde bulundur:

class Computer
  def new(cpus)
    @cpus = cpus
  end
end

Bu durumda, yaparsanız Computer.new, instance_variable_getulaşmak için kullanmak zorunda kalırsınız @cpus. Ancak bunu yapıyorsanız, muhtemelen @cpushalka açık olmayı kastediyorsunuz . Yapmanız gereken şey:

class Computer
  attr_reader :cpus
end

Şimdi yapabilirsin Computer.new(4).cpus.

Mevcut herhangi bir sınıfı yeniden açabileceğinizi ve okuyucuya özel bir ivar yapabileceğinizi unutmayın. Erişimci yalnızca bir yöntem olduğundan, şunları yapabilirsiniz:Computer.new(4).send(var_that_evaluates_to_cpus)


İnstance_variable_get ("@ # {name}") değişkenin değerini döndürmez mi? Gerçek nesneye bir referansa ihtiyacım var. Yeniden yazmaya başladım, böylece çok sayıda değişken + isimleri istediğim sırayla içeren bir dizi yerine, parametreleri diziye koydum (tasarım kararı, değişkenlere her seferinde diziyi arayarak mı yoksa bir sadece gerektiğinde kullanılacak isimleriyle ek dizi)
LK__

Hayır: instance_variable_get ("@ # {ad}") gerçek nesneyi döndürür.
Yehuda Katz 05

Biraz netlik için ölü ipliği ortaya çıkarmak. Tam örnek şöyle olacaktır: class Computer attr_read: cpus def new (cpus) @cpus = cpus end end?
Nicolas de Fontenay

"Bununla birlikte, kendinizi başka bir nesneye uzanıp onun ivarını çıkarırken bulursanız, kapsüllemeyi kırmış olma ihtimaliniz oldukça yüksektir." Başka bir nesnenin yumruğuna nasıl girebiliriz?
RubyMiner

9

Bir örnek değişkeninin adından bir örnek değişkeni almak için şunları yapın:

name = "paramName"
instance_variable_get(("@" + name).intern)

Bu, örnek değişkeninin değerini döndürür @paramName


Dinamik olarak bir sınıf oluştururken, örnek değişken isimlerinden oluşan bir diziye sahibim (bu listeye ihtiyacım var çünkü onları belirli bir sırada işlemem gerekiyor). Bu adı kullanarak değişkene bir referans almak istiyorum.
LK__

1
Bir "paramName" dizem var ve @paramName için bir referansa ihtiyacım var
LK__

1
TAMAM. Tam olarak bu iki yorumu söylemek için sorunuzu düzenlemenizi tavsiye ederim.
Daniel Lucraft

2
Ayrıca, bunun seriyi kaldırma ile hiçbir ilgisi yoktur. Daha iyi bir başlık "Adı verilen bir örnek değişkeninin değerini alın" veya başka bir şey olabilir.
Daniel Lucraft

Her zaman bir Modül yapabilir ve ekleyebilirsiniz, :attr_reader varnameböylece değişkenlere daha temiz ve daha az ayrıntılı bir şekilde erişebilirsiniz.
ocodo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.