2010-03-23 7 views
13

Ich benutze eine Menge von Iterationen Komfortmethoden in meinen Modellen zu definieren, Sachen wie:Dynamisch definierte Setter-Methoden mit define_method?

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

aber ich habe nie in der Lage gewesen, dynamisch Setter-Methoden zu definieren, das heißt:

def pet_name=(name) 
... 
end 

mit define_method wie folgt:

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

Irgendwelche Ideen? Danke im Voraus.

Antwort

37

Hier ist ein ziemlich vollständiges Beispiel der Verwendung define_method in einem Modul, das Sie Ihre Klasse verwenden zu verlängern:

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 

Ausgang:

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

Sie waren in der Nähe, aber Sie wollen nicht Fügen Sie das Argument der Methode in die Argumente Ihres Aufrufs bis define_method ein. Die Argumente gehen in den Block, den Sie an define_method übergeben.

1

Shoertly, wenn Sie es in einer Klasse/Modul benötigen: Ich benutze Hash, aber Sie können dort Anordnung von Elementen usw. setzen

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) } 
Verwandte Themen