jeudi 17 janvier 2008

MetaTricks : define_method

Un bon programmeur est un programmeur feignant... Et en Ruby, il existe une façon relativement simple d'éviter de coder : la méthode define_method. De quoi devenir vraiment feignant (donc vraiment bon !) grâce à la métaprogrammation !


L'exemple suivant est un cas simple. Après avoir défini une méthode mult (multiplication) pour la classe des entiers, je souhaite définir les méthodes mult_by_0, ..., mult_by_10 automatiquement. C'est ce qui est fait dans la première boucle grâce à define_method. Cette méthode prend en entrée le nom de la méthode à définir et lui affecte pour implémentation la closure (ici "mult int").
La vérification que les méthodes d'instances correspondantes ont bien été définies (et pas mult_by_11) est assuré par l'impression de la dernière boucle.

Le code :



class Integer
def mult by
self * by
end

(0..10).each{|int|
define_method("mult_by_#{int}") do
mult int
end
}
end

(0..11).each{|int|
boo = (1.respond_to? "mult_by_#{int}".to_sym)? \
"" : "don't "
puts "Integers #{boo}respond to mult_by_#{int}"
}


Où est la sorcellerie ?

0 commentaires: