3. “Para qué voy a
hacer [tarea X] si
puedo escribir un
programa que lo
haga por mí”
Cualquier programador,
en cualquier momento,
ante cualquier situación
27. method_missing
class Array
def method_missing(meth, *args, &blk)
if meth.to_s =~ /^map_(.+)$/
map {|i| i.send($1)}
else
super
end
end
end
(1..5).to_a.map_to_s
28. method_missing
class Array
def method_missing(meth, *args, &blk)
if meth.to_s =~ /^map_(.+)$/
map {|i| i.send($1)}
else
super
end
end
end
(1..5).to_a.map_to_s
>> [quot;1quot;, quot;2quot;, quot;3quot;, quot;4quot;, quot;5quot;]
30. const_missing
class Module
alias :normal_const_missing :const_missing
def const_missing(cname)
return normal_const_missing(cname) rescue nil
unless table_name = SchemaLookup.models[cname]
raise NameError.new(quot;uninitialized constant #{cname}quot;)
end
klass = Class.new(ActiveRecord::Base)
const_set cname, klass
klass.set_table_name table_name
klass
end
end
32. alias
class String
alias :largo :length
end
puts quot;holaquot;.largo
puts quot;holaquot;.length
33. alias
class String
alias :largo :length
end
puts quot;holaquot;.largo 4
puts quot;holaquot;.length 4
34. alias
class String
alias :largo :length
end
puts quot;holaquot;.largo 4
puts quot;holaquot;.length 4
class String
alias :old_length :length
def length
old_length + 2
end
end
puts quot;holaquot;.length
35. alias
class String
alias :largo :length
end
puts quot;holaquot;.largo 4
puts quot;holaquot;.length 4
class String
alias :old_length :length
def length
old_length + 2
end
end
puts quot;holaquot;.length 6
37. alias_method_chain
(el estándar de Rails para añadir funcionalidad a un método preexistente)
class String
def length_with_message
puts quot;Calculando longitud de #{self}quot;
length_without_message
end
alias_method_chain :length, :message
end
puts quot;holaquot;.length
38. alias_method_chain
(el estándar de Rails para añadir funcionalidad a un método preexistente)
class String
def length_with_message
puts quot;Calculando longitud de #{self}quot;
length_without_message
end
alias_method_chain :length, :message
end
puts quot;holaquot;.length
Calculando longitud de hola
4
46. define_method y def
class Prueba
def foo
quot;fooquot;
end
define_method(:bar) do
quot;barquot;
end
end
p = Prueba.new
puts p.foo
puts p.bar
47. define_method y def
class Prueba
def foo
quot;fooquot;
end
define_method(:bar) do
quot;barquot;
end
end
p = Prueba.new
puts p.foo foo
puts p.bar bar
49. ¿¿Y entonces??
class Prueba
[ :foo, :bar, :jander, :klander ].each do |m|
define_method(m) do
m.to_s
end
end
end
p = Prueba.new
puts p.foo
puts p.bar
puts p.jander
puts p.klander
50. ¿¿Y entonces??
class Prueba
[ :foo, :bar, :jander, :klander ].each do |m|
define_method(m) do
m.to_s
end
end
end
p = Prueba.new
foo
puts p.foo
bar
puts p.bar
jander
puts p.jander
klander
puts p.klander
51. Versión para realmente vagos
M = [ :foo, :bar, :jander, :klander ]
class Prueba
M.each do |m|
define_method(m) do
m.to_s
end
end
end
foo
bar
p = Prueba.new
jander
M.each do |m|
klander
puts p.send(m)
end
56. Usa módulos (mixins) para extender clases
class String
def italianize
self.gsub(/[aeiou]/, 'i')
end
end
57. Usa módulos (mixins) para extender clases
module Italianization
class String
def italianize
def italianize
self.gsub(/[aeiou]/, 'i')
self.gsub(/[aeiou]/, 'i')
end
end
end
end
String.send(:include, Italianization)
59. ¿Y por qué?
1. Gracias al const_missing de
Rails, no importa el orden en
que carguen las definiciones
60. ¿Y por qué?
1. Gracias al const_missing de
Rails, no importa el orden en
que carguen las definiciones
2. Más fácil de depurar
61. ¿Y por qué?
1. Gracias al const_missing de
Rails, no importa el orden en
que carguen las definiciones
2. Más fácil de depurar
String.ancestors
62. ¿Y por qué?
1. Gracias al const_missing de
Rails, no importa el orden en
que carguen las definiciones
2. Más fácil de depurar
String.ancestors
>> [ String, Enumerable, Comparable, Object, Kernel ]
63. ¿Y por qué?
1. Gracias al const_missing de
Rails, no importa el orden en
que carguen las definiciones
2. Más fácil de depurar
String.ancestors
>> [ String, Enumerable, Comparable, Object, Kernel ]
>> [ String, Italianization, Enumerable, Comparable, Object, Kernel ]
72. Referencias
quot;Metaprogramming Ruby: Domain-Specific Languages for Programmersquot;, Glenn Vanderburg [www.vanderburg.org/Speaking/Stu /oscon05.pdf]
quot;The art of metaprogrammingquot;, Jonhathan Bartlett [http://www-128.ibm.com/developerworks/linux/library/l-metaprog1.html]
C2.com Wiki [http://c2.com/cgi/wiki?MetaProgramming]
http://api.rubyonrails.org/
Ola Bini [http://ola-bini.blogspot.com/]
Jay Fields [http://blog.jayfields.com/]
Nic Williams [http://drnicwilliams.com/]
Lambda the Ultimate [http://lambda-the-ultimate.org/]
LiveValidation Plugin [http://livevalidation.rubyforge.org]
Sofá Naranja [http://sofanaranja.com/2007/09/19/elogio-de-la-vagancia/]