Metaprogramación (en Ruby): programas que escriben programas

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    3 Favorites

    Metaprogramación (en Ruby): programas que escriben programas - Presentation Transcript

    1. (en Ruby) Metaprogramación Programas que escriben programas Sergio Gil
    2. Sólo para vagos
    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
    4. Programar no es una excepción
    5. Automatización
    6. Acercar el lenguaje al problema (para resolverlo mejor)
    7. Qué es la metaprogramación y de dónde ha salido semejante cosa
    8. puts \"puts 'hola'\" $ ruby -e \"`ruby hola.rb`\"
    9. Programas que escriben otros programas Programas que modifican su propio comportamiento (es decir, se escriben a sí mismos)
    10. “In Lisp, you don’t just write your program down toward the language, you also build the language up toward your program.” Paul Graham
    11. Tipos de metaprogramación
    12. Estática / Interna
    13. Dinámica / Interna
    14. Metaprogramación en Rails
    15. Metaprogramación en Rails • Generadores
    16. Metaprogramación en Rails • Generadores • Métodos mágicos
    17. Metaprogramación en Rails • Generadores • Métodos mágicos • method_missing
    18. Metaprogramación en Rails • Generadores • Métodos mágicos • method_missing • const_missing
    19. Metaprogramación en Rails • Generadores • Métodos mágicos • method_missing • const_missing • Definiciones dinámicas
    20. Metaprogramación en Rails • Generadores • Métodos mágicos • method_missing • const_missing • Definiciones dinámicas $ grep -r method_missing vendor/rails/ | wc -l 72
    21. Metaprogramación en Rails • Generadores • Métodos mágicos • method_missing • const_missing • Definiciones dinámicas $ grep -r method_missingvendor/rails/ ||wc -l const_missing vendor/rails/ wc -l 41 72
    22. Metaprogramación en Rails • Generadores • Métodos mágicos • method_missing • const_missing • Definiciones dinámicas $ grep -r method_missingvendor/rails/ ||wc -l define_method const_missing vendor/rails/ wc -l 67 41 72
    23. Técnicas en Ruby/Rails
    24. Generadores
    25. Generadores class ModelGenerator < Rails::Generator::NamedBase def manifest record do |m| m.directory File.join('app/models', class_path) m.directory File.join('test/unit', class_path) m.directory File.join('test/fixtures', class_path) m.template 'model.rb', File.join('app/models', class_path, \"#{file_name}.rb\") m.template 'unit_test.rb', File.join('test/unit', class_path, \"#{file_name}_test.rb\") m.template 'fixtures.yml', File.join('test/fixtures', \"#{table_name}.yml\") m.migration_template 'migration.rb', 'db/migrate', :assigns => { :migration_name => \"Create#{class_name.pluralize.gsub(/::/, '')}\" }, :migration_file_name => \"create_#{file_path.gsub(/\\//, '_').pluralize}\" end end end
    26. method_missing
    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 >> [\"1\", \"2\", \"3\", \"4\", \"5\"]
    29. const_missing
    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(\"uninitialized constant #{cname}\") end klass = Class.new(ActiveRecord::Base) const_set cname, klass klass.set_table_name table_name klass end end
    31. alias
    32. alias class String alias :largo :length end puts \"hola\".largo puts \"hola\".length
    33. alias class String alias :largo :length end puts \"hola\".largo 4 puts \"hola\".length 4
    34. alias class String alias :largo :length end puts \"hola\".largo 4 puts \"hola\".length 4 class String alias :old_length :length def length old_length + 2 end end puts \"hola\".length
    35. alias class String alias :largo :length end puts \"hola\".largo 4 puts \"hola\".length 4 class String alias :old_length :length def length old_length + 2 end end puts \"hola\".length 6
    36. alias_method_chain (el estándar de Rails para añadir funcionalidad a un método preexistente)
    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 \"Calculando longitud de #{self}\" length_without_message end alias_method_chain :length, :message end puts \"hola\".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 \"Calculando longitud de #{self}\" length_without_message end alias_method_chain :length, :message end puts \"hola\".length Calculando longitud de hola 4
    39. send y define_method la metaprogramación pata negra
    40. send
    41. send str = \"Metaprogramaciongue\" puts str.upcase puts str.send(:upcase)
    42. send str = \"Metaprogramaciongue\" puts str.upcase METAPROGRAMACIONGUE puts str.send(:upcase) METAPROGRAMACIONGUE
    43. send str = \"Metaprogramaciongue\" puts str.upcase METAPROGRAMACIONGUE puts str.send(:upcase) METAPROGRAMACIONGUE [ :upcase, :downcase, :reverse ].each do |m| puts str.send(m) end
    44. send str = \"Metaprogramaciongue\" puts str.upcase METAPROGRAMACIONGUE puts str.send(:upcase) METAPROGRAMACIONGUE [ :upcase, :downcase, :reverse ].each do |m| METAPROGRAMACIONGUE puts str.send(m) metaprogramaciongue end eugnoicamargorpateM
    45. define_method y def
    46. define_method y def class Prueba def foo \"foo\" end define_method(:bar) do \"bar\" end end p = Prueba.new puts p.foo puts p.bar
    47. define_method y def class Prueba def foo \"foo\" end define_method(:bar) do \"bar\" end end p = Prueba.new puts p.foo foo puts p.bar bar
    48. ¿¿Y entonces??
    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
    52. Un ejemplo pequeño (pero real) de algunas de estas cosas juntas
    53. VALIDATION_METHODS = [:presence, :numericality, :format, :length, :acceptance, :confirmation] VALIDATION_METHODS.each do |type| define_method \"validates_#{type}_of_with_live_validations\".to_sym do |*attr_names| send \"validates_#{type}_of_without_live_validations\".to_sym, *attr_names define_validations(type, attr_names) end alias_method_chain \"validates_#{type}_of\".to_sym, :live_validations end
    54. Un consejito
    55. Usa módulos (mixins) para extender clases
    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)
    58. ¿Y por qué?
    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 ]
    64. Recapitulando
    65. 1. Sé vago
    66. 1. Sé vago 2. Pero no te pases de listo
    67. 1. Sé vago 2. Pero no te pases de listo 3. Y testea
    68. ¿Preguntas, dudas?
    69. ¿Preguntas, dudas? ¿Opiniones?
    70. Referencias \"Metaprogramming Ruby: Domain-Specific Languages for Programmers\", Glenn Vanderburg [www.vanderburg.org/Speaking/Stu /oscon05.pdf] \"The art of metaprogramming\", 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/]
    71. Muchas gracias sergio.gil@the‐cocktail.com lacoctelera.com/porras the‐cocktail.com

    + sergio.gilsergio.gil, 2 years ago

    custom

    2391 views, 3 favs, 2 embeds more stats

    Ponencia sobre metaprogramación en la Conferencia more

    More Info

    © All Rights Reserved

    Go to text version
    • Total Views 2391
      • 2338 on SlideShare
      • 53 from embeds
    • Comments 0
    • Favorites 3
    • Downloads 56
    Most viewed embeds
    • 52 views on http://www.lacoctelera.com
    • 1 views on http://www.netvibes.com

    more

    All embeds
    • 52 views on http://www.lacoctelera.com
    • 1 views on http://www.netvibes.com

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as innappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel

    Categories