2010-03-23 3 views
13

J'utilise beaucoup d'itérations pour définir des méthodes pratiques dans mes modèles, des trucs comme:Méthodes setter définies dynamiquement en utilisant define_method?

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

mais je ne l'ai jamais été en mesure de définir dynamiquement des méthodes de réglage, à savoir:

def pet_name=(name) 
... 
end 

utilisant define_method comme si:

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

Des idées? Merci d'avance.

Répondre

37

Voici un exemple assez complet de l'utilisation define_method dans un module que vous utilisez pour étendre votre 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 

Sortie:

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

Vous étiez proche, mais vous ne voulez pas inclure l'argument de la méthode dans les arguments de votre appel à define_method. Les arguments vont dans le bloc que vous passez à define_method.

1

Shoertly si vous avez besoin à l'intérieur d'une classe/Module: J'utilise hachage, mais vous pouvez y mettre ensemble d'éléments, 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) }