Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ruby Metaprogramming

Ruby Metaprogramming

Slides from my talk at #codemotion #es (Madrid, March 24th 2012).

http://codemotion.es/

45742831d67c80d12cd7b24907b8d760?s=128

Sergio Gil

March 25, 2012
Tweet

Transcript

  1. Ruby Metaprogramming Sergio Gil (@porras)

  2. None
  3. require 'excel' require 'sql' Excel.load('file.xls').each do |row| SQL.insert(row) end

  4. None
  5. require 'html' require 'http' page = HTML.load(HTTP.get('http://example.com/')) page.links.each do |link|

    HTTP.get(link).save end
  6. class Company def projects HTTP::Request.new('/projects').get end def people HTTP::Request.new('/people').get end

    def clients HTTP::Request.new('/clients').get end ... end
  7. Yukihiro Matsumoto ‘Matz’, Ruby creator

  8. None
  9. Metaprogramming

  10. defining metaprogramming

  11. None
  12. None
  13. None
  14. None
  15. Classes Instances Methods Variables Constants Modules

  16. Classes Instances Methods Variables Constants Modules

  17. Memory

  18. Classes Instances Methods Variables Constants Modules

  19. None
  20. >> str = "hola" => "hola"

  21. >> str = "hola" => "hola" >> str.methods => [...,

    :reverse, ...]
  22. >> str = "hola" => "hola" >> str.methods => [...,

    :reverse, ...] >> def str.reverse "adios" end
  23. >> str = "hola" => "hola" >> str.methods => [...,

    :reverse, ...] >> def str.reverse "adios" end >> str.reverse
  24. >> str = "hola" => "hola" >> str.methods => [...,

    :reverse, ...] >> def str.reverse "adios" end >> str.reverse => "adios"
  25. Ruby Object Model: The Musical

  26. None
  27. None
  28. None
  29. None
  30. None
  31. It’s all about DRYness

  32. class Company def projects HTTP::Request.new('/projects').get end def people HTTP::Request.new('/people').get end

    ... end
  33. class Company def projects get('/projects') end def people get('/people') end

    ... private def get(url) HTTP::Request.new(url).get end end
  34. Is that all?

  35. Let Ruby create your methods for you

  36. class Company [:projects, :people, ...].each do |method| eval %Q{ def

    #{method} HTTP::Request.new('/#{method}').get end } end end
  37. class Company [:projects, :people, ...].each do |method| define_method method do

    HTTP::Request.new("/#{method}").get end end end
  38. None
  39. It’s all about expresivity

  40. None
  41. module HTTP def get(*methods) methods.each do |method| define_method method do

    HTTP::Request.new("/#{method}").get end end end end
  42. module HTTP def get(*methods) methods.each do |method| define_method method do

    HTTP::Request.new("/#{method}").get end end end end class Company extend HTTP get :projects, :people, ... end
  43. “I Taw a Putty DSL...”

  44. class Company extend HTTP get :projects, :people, ... end

  45. It’s all about flexibility

  46. class Company def method_missing(method, *args, &blk) HTTP::Request.new("/#{method}").get end end

  47. class Company def method_missing(method, *args, &blk) HTTP::Request.new("/#{method}").get end end

  48. It’s all common sense

  49. metaprogramming == programming

  50. same trade-offs apply

  51. None
  52. None
  53. None
  54. “Cleverness cannot win. The only weapons we have are simplicity

    and convention” http://alarmingdevelopment.org/?p=422
  55. Thank you :)