2010-03-23 16 views
13

que utilizan una gran cantidad de iteraciones para definir métodos de conveniencia en mis modelos, cosas como:métodos setter definidos dinámicamente usando define_method?

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

pero nunca he sido capaz de definir dinámicamente métodos setter, es decir:

def pet_name=(name) 
... 
end 

utilizando define_method como el siguiente:

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

¿Alguna idea? Gracias por adelantado.

Respuesta

37

Aquí está un ejemplo bastante completo de la utilización de define_method en un módulo que se utiliza para extender su clase:

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 

Salida:

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

estaban cerca, pero no quiere incluya el argumento del método dentro de los argumentos de su llamada al define_method. Los argumentos van en el bloque que pasa al define_method.

1

Shoertly si lo necesita dentro de una clase/módulo: uso de hash, pero se puede poner allí matriz de elementos etc.

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) } 
Cuestiones relacionadas