2010-03-23 13 views
13

Io uso un sacco di iterazioni per definire metodi di convenienza nei miei modelli, cose del genere:Metodi di setter definiti dinamicamente usando define_method?

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

ma non sono mai stato in grado di definire dinamicamente metodi setter, vale a dire:

def pet_name=(name) 
... 
end 

utilizzando define_method così:

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

Qualche idea? Grazie in anticipo.

risposta

37

Ecco un esempio abbastanza pieno di utilizzare define_method in un modulo che si utilizza per estendere la vostra classe:

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 

uscita:

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

Eri vicino, ma non si vuole includi l'argomento del metodo all'interno degli argomenti della tua chiamata a define_method. Gli argomenti vanno nel blocco che si passa a define_method.

1

Shoertly se ne avete bisogno all'interno di una classe/modulo: Io uso hash, ma che ci può mettere array di elementi ecc

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) } 
Problemi correlati