2010-03-23 27 views
13

benim modellerinde kolaylık yöntemlerini tanımlamak için tekrarlamalar bir çok kullanmak, malzeme gibi:define_method kullanarak dinamik olarak tanımlanmış ayarlayıcı yöntemleri?

PET_NAMES.each do |pn| 
define_method(pn) do 
... 
... 
end 

ama dinamik setter yöntemleri yani tanımlamak mümkün olmamıştım:

def pet_name=(name) 
... 
end 

define_method kullanarak böyle:

define_method("pet_name=(name)") do 
... 
end 

Herhangi bir fikir? Şimdiden teşekkürler.

cevap

37

Burada sınıfını genişletmek için kullandıkları bir modülde define_method kullanmanın oldukça dolu örnek:

module VerboseSetter 
    def make_verbose_setter(*names) 
    names.each do |name| 
     define_method("#{name}=") do |val| 
     puts "@#{name} was set to #{val}" 
     instance_variable_set("@#{name}", val) 
     end 
    end 
    end 
end 

class Foo 
    extend VerboseSetter 

    make_verbose_setter :bar, :quux 
end 

f = Foo.new 
f.bar = 5 
f.quux = 10 

Çıktı:

 
@bar was set to 5 
@quux was set to 10 

Sen yakın, ama sen istemiyorsun numaralı aralığınızın bağımsız değişkenleri içindeki yöntemin argümanını define_method'a ekleyin. Argümanlar, define_method'a ilettiğiniz blokta gider. Bir sınıf/modülü içinde ihtiyaç Shoertly eğer

1

: Ben karma kullanmak ancak vb elemanlar

PETS = { 
    "cat" => "meyow", 
    "cow" => "moo", 
    "dog" => "ruff" 
} 

def do_smth1(v) 
... 
end 

def do_smth(sound,v) 
... 
end 

#getter 
PETS.each{ |k,v| define_method(k){ do_smth1(v) } } 

#setter 
PETS.each{ |k,v| define_method("#{k}="){|sound| do_smth2(sound, v) } 
arasında orada dizisi koyabilirsiniz
İlgili konular