SlideShare a Scribd company logo
metaprogramming
        +
     domain
     specific
   languages
%  cat  ddfreyne.txt

DENIS  DEFREYNE
==============

web:          http://stoneship.org
twitter:  ddfreyne

nanoc:  a  static  ruby  web  site  publishing  system
http://nanoc.stoneship.org/

%  _
what is
metaprogramming?
Metaprogramming is the
   writing of computer
 programs that write or
    manipulate other
programs (or themselves)
       as their data.
class  Person

    attr_reader  :friends

end
class  Document  <  ActiveRecord::Base

    has_many  :pages

end
task  :test  do
    puts  "Hello,  I  am  a  rake  task!"
end
example (i)
class  Bob
    my_attr_reader  :foo,  :bar
end
class  Module

    def  my_attr_reader(*fields)
        fields.each  do  |field|

            class_eval  "
                def  #{field}
                    @#{field}
                end
            "

        end
    end

end
class  Module

    def  my_attr_reader(*fields)
        fields.each  do  |field|

            class_eval  "
                def  #{field}
                    @#{field}
                end
            "

        end
    end

end
def  #{field}
    @#{field}
end
def  foo
    @foo
end
def  bar
    @bar
end
class  Module

    def  my_attr_reader(*fields)
        fields.each  do  |field|

            class_eval  "
                def  #{field}
                    @#{field}
                end
            "

        end
    end

end
DEMO
example (ii)
class  Module

    def  my_attr_reader(*fields)
        fields.each  do  |field|

            class_eval  "
                def  #{field}
                    @#{field}
                end
            "

        end
    end

end
class  Module

    def  battr_reader(*fields)
        fields.each  do  |field|

            class_eval  "
                def  #{field}?
                    !!@#{field}
                end
            "

        end
    end

end
class  Bob
    battr_reader  :foo,  :bar
end

p  bob.foo?
p  bob.bar?
DEMO
example (iii)
<p>Hello.  My  name  is  <%=  @first_name  %>.</p>
template  =  "<p>Hello.  My  name  is  <%=
    @first_name  %>.</p>"

@first_name  =  "Bob"

p  ERB.new(template).result
DEMO
example (iv)
class  Product
    def  initialize
        @title  =  "My  First  Ruby  Book"
        @id        =  "39t8zfeg"
    end
end

template  =  "<p>Product  <%=
    @id  %>  has  title  <%=  @title  %>.</p>"

product  =  Product.new

#  TODO  use  the  product  details  
p  ERB.new(template).result
class  Product
    def  initialize
        @title  =  "My  First  Ruby  Book"
        @id        =  "39t8zfeg"
    end

    def  print
        template  =  "<p>Product  <%=
            @id  %>  has  title  <%=  @title  %>.</p>"

        puts  ERB.new(template).result(binding)
    end
end
class  Product
    def  initialize
        @title  =  "My  First  Ruby  Book"
        @id        =  "39t8zfeg"
    end

    def  print
        template  =  "<p>Product  <%=
            @id  %>  has  title  <%=  @title  %>.</p>"

        puts  ERB.new(template).result(binding)
    end
end
class  Product

    def  initialize
        @title  =  "My  First  Ruby  Book"
        @id        =  "39t8zfeg"
    end




end
class  Product

    def  initialize
        @title  =  "My  First  Ruby  Book"
        @id        =  "39t8zfeg"
    end

    def  get_binding
        binding
    end

end
def  get_binding
    binding
end
def  get_binding
    binding
end
def  binding
    binding
end
def  binding
    binding
end

SystemStackError:  stack  level  too  deep
template  =  "<p>Product  <%=
    @id  %>  has  title  <%=  @title  %>.</p>"

product  =  Product.new

p  ERB.new(template).result
template  =  "<p>Product  <%=
    @id  %>  has  title  <%=  @title  %>.</p>"

product  =  Product.new

p  ERB.new(template).result(product.get_binding)
DEMO
example (v)
compile  '/articles/*/'  do
    filter  :erb
    filter  :bluecloth

    layout  'article'

    filter  :rubypants
end
my-­‐site/
    config.yaml
    Rules
    content/
    layouts/
    lib/
… simpler

process  /oo/  do  |item|
    puts  "I  am  rule  /oo/!"
    puts  "I  am  processing  #{item.inspect}!"
end
class  Item

    attr_reader  :identifier

    def  initialize(identifier)
        @identifier  =  identifier
    end

end
items  =  [
    Item.new('foo'),
    Item.new('foobar'),
    Item.new('quxbar'),
    Item.new('moo')
]

magically_load_rules

items.each  do  |item|
    magically_process(item)
end
class  Rule

    def  initialize(pattern,  block)
        @pattern  =  pattern
        @block      =  block
    end

    def  applicable_to?(item)
        item.identifier  =~  @pattern
    end

    def  apply_to(item)
        @block.call(item)
    end

end
class  Application

    def  initialize
        @rules  =  []
    end

    def  load_rules
        rules_content  =  File.read('Rules')
        dsl  =  DSL.new(@rules)
        dsl.instance_eval(rules_content)
    end

    ⋮
class  Application

    def  initialize
        @rules  =  []
    end

    def  load_rules
        rules_content  =  File.read('Rules')
        dsl  =  DSL.new(@rules)
        dsl.instance_eval(rules_content)
    end

    ⋮
class  Bob

    def  initialize
        @secret  =  "abc"
    end

end
bob  =  Bob.new
p  bob.secret

NoMethodError:  undefined  method  `secret'
    for  #<Bob:0x574324>
bob  =  Bob.new
p  bob.instance_eval  {  @secret  }

abc
bob  =  Bob.new
p  bob.instance_eval  "@secret"

abc
class  Application

    def  initialize
        @rules  =  []
    end

    def  load_rules
        rules_content  =  File.read('Rules')
        dsl  =  DSL.new(@rules)
        dsl.instance_eval(rules_content)
    end

    ⋮
   ⋮

    def  process(item)
        rule  =  rules.find  do  |r|
            r.applicable_to?(item)
        end

        rule.apply_to(item)
    end

end
class  DSL

    def  initialize(rules)
        @rules  =  rules
    end

    def  process(pattern,  &block)
        @rules  <<  Rule.new(pattern,  block)
    end

end
class  DSL

    def  initialize(rules)
        @rules  =  rules
    end

    def  process(pattern,  &block)
        @rules  <<  Rule.new(pattern,  block)
    end

end
process  /oo/  do  |item|
    puts  "I  am  rule  /oo/!"
    puts  "I  am  processing  #{item.inspect}!"
end
process  /oo/  do  |item|
    puts  "I  am  rule  /oo/!"
    puts  "I  am  processing  #{item.inspect}!"
end
items  =  [
    Item.new('foo'),
    Item.new('foobar'),
    Item.new('quxbar'),
    Item.new('moo')
]

app  =  App.new
app.load_rules

items.each  do  |item|
    app.process(item)
end
DEMO
example (vi)
process  /oo/  do  |item|
    puts  "I  am  rule  /oo/!"
    puts  "I  am  processing  #{item.inspect}!"
end
process  /oo/  do
    puts  "I  am  rule  /oo/!"
    puts  "I  am  processing  #{item.inspect}!"
end
class  RuleContext

    def  initialize(item)
        @item  =  item
    end

end
class  Rule

    def  initialize(pattern,  block)
        @pattern  =  pattern
        @block      =  block
    end

    def  applicable_to?(item)
        item.identifier  =~  @pattern
    end

    def  apply_to(item)
        #  original  way:
        @block.call(item)
    end

end
class  Rule

    def  initialize(pattern,  block)
        @pattern  =  pattern
        @block      =  block
    end

    def  applicable_to?(item)
        item.identifier  =~  @pattern
    end

    def  apply_to(item)
        rule_context  =  RuleContext.new(item)
        rule_context.instance_eval(&@block)
    end

end
process  /oo/  do
    puts  "I  am  rule  /oo/!"
    puts  "I  am  processing  #{@item.inspect}!"
end
process  /oo/  do
    puts  "I  am  rule  /oo/!"
    puts  "I  am  processing  #{item.inspect}!"
end
class  RuleContext

    def  initialize(item)
        @item  =  item
    end




end
class  RuleContext

    def  initialize(item)
        @item  =  item
    end

    def  item
        @item
    end

end
process  /oo/  do
    puts  "I  am  rule  /oo/!"
    puts  "I  am  processing  #{item.inspect}!"
end
DEMO
‣ The Ruby Object Model
  and Metaprogramming
  http://www.pragprog.com/screencasts/v-
  dtrubyom/the-ruby-object-model-and-
  metaprogramming

‣ How nanocʼs Rules DSL Works
  http://stoneship.org/journal/2009/how-
  nanocs-rules-dsl-works/
you can haz
questions?
k thx bai

More Related Content

PDF
Advanced Django
PDF
Real life-coffeescript
PDF
Class-based views with Django
PDF
Using java beans(ii)
PDF
model.search: customize your own search logic
ODP
Perl Teach-In (part 2)
PPTX
jQuery PPT
PPTX
Art of Javascript
Advanced Django
Real life-coffeescript
Class-based views with Django
Using java beans(ii)
model.search: customize your own search logic
Perl Teach-In (part 2)
jQuery PPT
Art of Javascript

What's hot (17)

PDF
Any tutor
PPTX
LinkedIn TBC JavaScript 100: Intro
PPT
Javascript and Jquery Best practices
PDF
Secrets of JavaScript Libraries
PPTX
Basics of Java Script (JS)
PPTX
Javascript best practices
PDF
Performance Optimization and JavaScript Best Practices
PDF
Scalable JavaScript Design Patterns
PPTX
JavaScript Literacy
PPTX
Introduction to PHP Lecture 1
PPT
Javascript
PPT
Javascript Object Oriented Programming
PPTX
jQuery from the very beginning
PPTX
Powerful Generic Patterns With Django
PDF
ORM in Django
PDF
A Gentle Introduction To Object Oriented Php
PPT
Beginning Object-Oriented JavaScript
Any tutor
LinkedIn TBC JavaScript 100: Intro
Javascript and Jquery Best practices
Secrets of JavaScript Libraries
Basics of Java Script (JS)
Javascript best practices
Performance Optimization and JavaScript Best Practices
Scalable JavaScript Design Patterns
JavaScript Literacy
Introduction to PHP Lecture 1
Javascript
Javascript Object Oriented Programming
jQuery from the very beginning
Powerful Generic Patterns With Django
ORM in Django
A Gentle Introduction To Object Oriented Php
Beginning Object-Oriented JavaScript
Ad

Viewers also liked (20)

PPS
2011 some photos
PPSX
Hoboes Expo2
PDF
Candidiasis invasiva
PPTX
Ogc in arc_gis_g_tstyle
PDF
¿Tratamiento antirretroviral como prevencion?
PDF
Tb XDR in South Africa
PDF
PPTX
Oer slides fall 2013
PDF
Guida Ebooks & iBooks Author
PPTX
PPT
Pubcon 2013 - Post mortem banned site forensics
PDF
Iii jal pres_avaluaciocompetencial
PPT
Smart Questions
PPTX
How to run asp.net on virtual server for $5 per mo
DOC
HOT N´COLD
PDF
Freelance Robotics Company Profile V1 2
PDF
Digital Mediaina state
2011 some photos
Hoboes Expo2
Candidiasis invasiva
Ogc in arc_gis_g_tstyle
¿Tratamiento antirretroviral como prevencion?
Tb XDR in South Africa
Oer slides fall 2013
Guida Ebooks & iBooks Author
Pubcon 2013 - Post mortem banned site forensics
Iii jal pres_avaluaciocompetencial
Smart Questions
How to run asp.net on virtual server for $5 per mo
HOT N´COLD
Freelance Robotics Company Profile V1 2
Digital Mediaina state
Ad

Similar to Metaprogramming + Ds Ls (20)

PDF
Designing Ruby APIs
KEY
PDF
Metaprogramming in Ruby
KEY
A tour on ruby and friends
KEY
Refactor like a boss
PDF
Ruby and Rails by Example (GeekCamp edition)
KEY
An introduction to Ruby
KEY
Ruby objects
PDF
Introduction to Ruby Programming Language
PDF
Steady with ruby
PDF
Ruby and rails - Advanced Training (Cybage)
PDF
Story for a Ruby on Rails Single Engineer
PPT
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
KEY
Desarrollando aplicaciones web en minutos
KEY
jRuby: The best of both worlds
PDF
Design Patterns the Ruby way - ConFoo 2015
PDF
Ruby 程式語言入門導覽
PDF
Metaprogramming 101
PPT
Ruby For Java Programmers
PDF
Ruby 入門 第一次就上手
Designing Ruby APIs
Metaprogramming in Ruby
A tour on ruby and friends
Refactor like a boss
Ruby and Rails by Example (GeekCamp edition)
An introduction to Ruby
Ruby objects
Introduction to Ruby Programming Language
Steady with ruby
Ruby and rails - Advanced Training (Cybage)
Story for a Ruby on Rails Single Engineer
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Desarrollando aplicaciones web en minutos
jRuby: The best of both worlds
Design Patterns the Ruby way - ConFoo 2015
Ruby 程式語言入門導覽
Metaprogramming 101
Ruby For Java Programmers
Ruby 入門 第一次就上手

More from ArrrrCamp (15)

PDF
Arrrrcamp Radiant Intro
KEY
Ruby 1.9 And Rails 3.0
PDF
Rubyandrails
PDF
Nanoc
PDF
PDF
Radiant
PDF
Mistakes
PDF
Railsservers
PDF
Prawn
PDF
Testing
PDF
Validation
PDF
Cucumber
PDF
Ruby and Rails Basics
PDF
Caching your rails application
PDF
Advanced Radiant
Arrrrcamp Radiant Intro
Ruby 1.9 And Rails 3.0
Rubyandrails
Nanoc
Radiant
Mistakes
Railsservers
Prawn
Testing
Validation
Cucumber
Ruby and Rails Basics
Caching your rails application
Advanced Radiant

Recently uploaded (20)

PDF
cuic standard and advanced reporting.pdf
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Unlocking AI with Model Context Protocol (MCP)
PPT
Teaching material agriculture food technology
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Machine learning based COVID-19 study performance prediction
PPTX
A Presentation on Artificial Intelligence
PDF
Encapsulation theory and applications.pdf
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
cuic standard and advanced reporting.pdf
Mobile App Security Testing_ A Comprehensive Guide.pdf
Unlocking AI with Model Context Protocol (MCP)
Teaching material agriculture food technology
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
20250228 LYD VKU AI Blended-Learning.pptx
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Digital-Transformation-Roadmap-for-Companies.pptx
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
Chapter 3 Spatial Domain Image Processing.pdf
Machine learning based COVID-19 study performance prediction
A Presentation on Artificial Intelligence
Encapsulation theory and applications.pdf
Understanding_Digital_Forensics_Presentation.pptx
Reach Out and Touch Someone: Haptics and Empathic Computing
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...

Metaprogramming + Ds Ls

  • 1. metaprogramming + domain specific languages
  • 2. %  cat  ddfreyne.txt DENIS  DEFREYNE ============== web:          http://stoneship.org twitter:  ddfreyne nanoc:  a  static  ruby  web  site  publishing  system http://nanoc.stoneship.org/ %  _
  • 4. Metaprogramming is the writing of computer programs that write or manipulate other programs (or themselves) as their data.
  • 5. class  Person    attr_reader  :friends end
  • 6. class  Document  <  ActiveRecord::Base    has_many  :pages end
  • 7. task  :test  do    puts  "Hello,  I  am  a  rake  task!" end
  • 9. class  Bob    my_attr_reader  :foo,  :bar end
  • 10. class  Module    def  my_attr_reader(*fields)        fields.each  do  |field|            class_eval  "                def  #{field}                    @#{field}                end            "        end    end end
  • 11. class  Module    def  my_attr_reader(*fields)        fields.each  do  |field|            class_eval  "                def  #{field}                    @#{field}                end            "        end    end end
  • 12. def  #{field}    @#{field} end
  • 13. def  foo    @foo end
  • 14. def  bar    @bar end
  • 15. class  Module    def  my_attr_reader(*fields)        fields.each  do  |field|            class_eval  "                def  #{field}                    @#{field}                end            "        end    end end
  • 16. DEMO
  • 18. class  Module    def  my_attr_reader(*fields)        fields.each  do  |field|            class_eval  "                def  #{field}                    @#{field}                end            "        end    end end
  • 19. class  Module    def  battr_reader(*fields)        fields.each  do  |field|            class_eval  "                def  #{field}?                    !!@#{field}                end            "        end    end end
  • 20. class  Bob    battr_reader  :foo,  :bar end p  bob.foo? p  bob.bar?
  • 21. DEMO
  • 23. <p>Hello.  My  name  is  <%=  @first_name  %>.</p>
  • 24. template  =  "<p>Hello.  My  name  is  <%=    @first_name  %>.</p>" @first_name  =  "Bob" p  ERB.new(template).result
  • 25. DEMO
  • 27. class  Product    def  initialize        @title  =  "My  First  Ruby  Book"        @id        =  "39t8zfeg"    end end template  =  "<p>Product  <%=    @id  %>  has  title  <%=  @title  %>.</p>" product  =  Product.new #  TODO  use  the  product  details   p  ERB.new(template).result
  • 28. class  Product    def  initialize        @title  =  "My  First  Ruby  Book"        @id        =  "39t8zfeg"    end    def  print        template  =  "<p>Product  <%=            @id  %>  has  title  <%=  @title  %>.</p>"        puts  ERB.new(template).result(binding)    end end
  • 29. class  Product    def  initialize        @title  =  "My  First  Ruby  Book"        @id        =  "39t8zfeg"    end    def  print        template  =  "<p>Product  <%=            @id  %>  has  title  <%=  @title  %>.</p>"        puts  ERB.new(template).result(binding)    end end
  • 30. class  Product    def  initialize        @title  =  "My  First  Ruby  Book"        @id        =  "39t8zfeg"    end end
  • 31. class  Product    def  initialize        @title  =  "My  First  Ruby  Book"        @id        =  "39t8zfeg"    end    def  get_binding        binding    end end
  • 32. def  get_binding    binding end
  • 33. def  get_binding    binding end
  • 34. def  binding    binding end
  • 35. def  binding    binding end SystemStackError:  stack  level  too  deep
  • 36. template  =  "<p>Product  <%=    @id  %>  has  title  <%=  @title  %>.</p>" product  =  Product.new p  ERB.new(template).result
  • 37. template  =  "<p>Product  <%=    @id  %>  has  title  <%=  @title  %>.</p>" product  =  Product.new p  ERB.new(template).result(product.get_binding)
  • 38. DEMO
  • 40. compile  '/articles/*/'  do    filter  :erb    filter  :bluecloth    layout  'article'    filter  :rubypants end
  • 41. my-­‐site/    config.yaml    Rules    content/    layouts/    lib/
  • 42. … simpler process  /oo/  do  |item|    puts  "I  am  rule  /oo/!"    puts  "I  am  processing  #{item.inspect}!" end
  • 43. class  Item    attr_reader  :identifier    def  initialize(identifier)        @identifier  =  identifier    end end
  • 44. items  =  [    Item.new('foo'),    Item.new('foobar'),    Item.new('quxbar'),    Item.new('moo') ] magically_load_rules items.each  do  |item|    magically_process(item) end
  • 45. class  Rule    def  initialize(pattern,  block)        @pattern  =  pattern        @block      =  block    end    def  applicable_to?(item)        item.identifier  =~  @pattern    end    def  apply_to(item)        @block.call(item)    end end
  • 46. class  Application    def  initialize        @rules  =  []    end    def  load_rules        rules_content  =  File.read('Rules')        dsl  =  DSL.new(@rules)        dsl.instance_eval(rules_content)    end    ⋮
  • 47. class  Application    def  initialize        @rules  =  []    end    def  load_rules        rules_content  =  File.read('Rules')        dsl  =  DSL.new(@rules)        dsl.instance_eval(rules_content)    end    ⋮
  • 48. class  Bob    def  initialize        @secret  =  "abc"    end end
  • 49. bob  =  Bob.new p  bob.secret NoMethodError:  undefined  method  `secret'    for  #<Bob:0x574324>
  • 50. bob  =  Bob.new p  bob.instance_eval  {  @secret  } abc
  • 51. bob  =  Bob.new p  bob.instance_eval  "@secret" abc
  • 52. class  Application    def  initialize        @rules  =  []    end    def  load_rules        rules_content  =  File.read('Rules')        dsl  =  DSL.new(@rules)        dsl.instance_eval(rules_content)    end    ⋮
  • 53.    ⋮    def  process(item)        rule  =  rules.find  do  |r|            r.applicable_to?(item)        end        rule.apply_to(item)    end end
  • 54. class  DSL    def  initialize(rules)        @rules  =  rules    end    def  process(pattern,  &block)        @rules  <<  Rule.new(pattern,  block)    end end
  • 55. class  DSL    def  initialize(rules)        @rules  =  rules    end    def  process(pattern,  &block)        @rules  <<  Rule.new(pattern,  block)    end end
  • 56. process  /oo/  do  |item|    puts  "I  am  rule  /oo/!"    puts  "I  am  processing  #{item.inspect}!" end
  • 57. process  /oo/  do  |item|    puts  "I  am  rule  /oo/!"    puts  "I  am  processing  #{item.inspect}!" end
  • 58. items  =  [    Item.new('foo'),    Item.new('foobar'),    Item.new('quxbar'),    Item.new('moo') ] app  =  App.new app.load_rules items.each  do  |item|    app.process(item) end
  • 59. DEMO
  • 61. process  /oo/  do  |item|    puts  "I  am  rule  /oo/!"    puts  "I  am  processing  #{item.inspect}!" end
  • 62. process  /oo/  do    puts  "I  am  rule  /oo/!"    puts  "I  am  processing  #{item.inspect}!" end
  • 63. class  RuleContext    def  initialize(item)        @item  =  item    end end
  • 64. class  Rule    def  initialize(pattern,  block)        @pattern  =  pattern        @block      =  block    end    def  applicable_to?(item)        item.identifier  =~  @pattern    end    def  apply_to(item)        #  original  way:        @block.call(item)    end end
  • 65. class  Rule    def  initialize(pattern,  block)        @pattern  =  pattern        @block      =  block    end    def  applicable_to?(item)        item.identifier  =~  @pattern    end    def  apply_to(item)        rule_context  =  RuleContext.new(item)        rule_context.instance_eval(&@block)    end end
  • 66. process  /oo/  do    puts  "I  am  rule  /oo/!"    puts  "I  am  processing  #{@item.inspect}!" end
  • 67. process  /oo/  do    puts  "I  am  rule  /oo/!"    puts  "I  am  processing  #{item.inspect}!" end
  • 68. class  RuleContext    def  initialize(item)        @item  =  item    end end
  • 69. class  RuleContext    def  initialize(item)        @item  =  item    end    def  item        @item    end end
  • 70. process  /oo/  do    puts  "I  am  rule  /oo/!"    puts  "I  am  processing  #{item.inspect}!" end
  • 71. DEMO
  • 72. ‣ The Ruby Object Model and Metaprogramming http://www.pragprog.com/screencasts/v- dtrubyom/the-ruby-object-model-and- metaprogramming ‣ How nanocʼs Rules DSL Works http://stoneship.org/journal/2009/how- nanocs-rules-dsl-works/