Ruby define_method e module_eval: ancora sulla metaprogrammazione
Posted by Dibi Store Tue, 04 Mar 2008 10:28:00 GMT
Continuo la serie di articoli riguardo la metaprogrammazione in Ruby mostrando un paio di metodi molto utili. I metodi che seguono permettono di creare rispettivamente un metodo di istanza (ossia che disponibile successivamente aver istanziato la classe) e un metodo di classe (richimabile senza aver istanziato la classe). Questi metodi sono molto utilizzati ad esempio nel sorgente di rails e ci permettono di usare tutti quei metodi come validates_presence_of che ci vengono regalati in molte classi. Notate nel secondo esempio come usiamo in modo appropriato il codice class << self.
class Test; end
Test.module_eval do
define_method :talk do
puts "This is cool!"
end
end
Test.new.talk # => This is cool!
Test.module_eval do
class << self
define_method :talk_again do
puts "This is more cool!"
end
end
end
Test.talk_again # => This is more cool!
Un applicazione reale? Immaginate di dover definire lo stesso metodo in dieci classi diverse contenute nell'array classi, potreste usare il codice seguente:
classi.each do |c|
c.module_eval do
define_method :validates... do |*args|
....
end
end
end
Notate che *args è un hash di argomenti che possono essere passati alla funzione, potete poi estrapolarli a vostro piacere. E' possibile anche dare un solo (o più) argomenti alla funzione con la seguente sintassi
define_method :name do |arg1, arg2| ... end.
Risorse: documentazione modulo

