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
Simon Willison
 
PDF
Real life-coffeescript
David Furber
 
PDF
Class-based views with Django
Simon Willison
 
PDF
Using java beans(ii)
Ximentita Hernandez
 
PDF
model.search: customize your own search logic
Tse-Ching Ho
 
ODP
Perl Teach-In (part 2)
Dave Cross
 
PPTX
jQuery PPT
Dominic Arrojado
 
PPTX
Art of Javascript
Tarek Yehia
 
Advanced Django
Simon Willison
 
Real life-coffeescript
David Furber
 
Class-based views with Django
Simon Willison
 
Using java beans(ii)
Ximentita Hernandez
 
model.search: customize your own search logic
Tse-Ching Ho
 
Perl Teach-In (part 2)
Dave Cross
 
jQuery PPT
Dominic Arrojado
 
Art of Javascript
Tarek Yehia
 

What's hot (17)

PDF
Any tutor
Yun-Yan Chi
 
PPTX
LinkedIn TBC JavaScript 100: Intro
Adam Crabtree
 
PPT
Javascript and Jquery Best practices
Sultan Khan
 
PDF
Secrets of JavaScript Libraries
jeresig
 
PPTX
Basics of Java Script (JS)
Ajay Khatri
 
PPTX
Javascript best practices
Manav Gupta
 
PDF
Performance Optimization and JavaScript Best Practices
Doris Chen
 
PDF
Scalable JavaScript Design Patterns
Addy Osmani
 
PPTX
JavaScript Literacy
David Jacobs
 
PPTX
Introduction to PHP Lecture 1
Ajay Khatri
 
PPT
Javascript
Manav Prasad
 
PPT
Javascript Object Oriented Programming
Bunlong Van
 
PPTX
jQuery from the very beginning
Anis Ahmad
 
PPTX
Powerful Generic Patterns With Django
Eric Satterwhite
 
PDF
ORM in Django
Hoang Nguyen
 
PDF
A Gentle Introduction To Object Oriented Php
Michael Girouard
 
PPT
Beginning Object-Oriented JavaScript
Stoyan Stefanov
 
Any tutor
Yun-Yan Chi
 
LinkedIn TBC JavaScript 100: Intro
Adam Crabtree
 
Javascript and Jquery Best practices
Sultan Khan
 
Secrets of JavaScript Libraries
jeresig
 
Basics of Java Script (JS)
Ajay Khatri
 
Javascript best practices
Manav Gupta
 
Performance Optimization and JavaScript Best Practices
Doris Chen
 
Scalable JavaScript Design Patterns
Addy Osmani
 
JavaScript Literacy
David Jacobs
 
Introduction to PHP Lecture 1
Ajay Khatri
 
Javascript
Manav Prasad
 
Javascript Object Oriented Programming
Bunlong Van
 
jQuery from the very beginning
Anis Ahmad
 
Powerful Generic Patterns With Django
Eric Satterwhite
 
ORM in Django
Hoang Nguyen
 
A Gentle Introduction To Object Oriented Php
Michael Girouard
 
Beginning Object-Oriented JavaScript
Stoyan Stefanov
 
Ad

Viewers also liked (20)

PPS
2011 some photos
Dirval Chareti
 
PPSX
Hoboes Expo2
guest293db1
 
PDF
Candidiasis invasiva
Alex Castañeda-Sabogal
 
PPTX
Ogc in arc_gis_g_tstyle
Gert-Jan
 
PDF
¿Tratamiento antirretroviral como prevencion?
Alex Castañeda-Sabogal
 
PDF
Tb XDR in South Africa
Alex Castañeda-Sabogal
 
PDF
Tomillo
jperezvega2009
 
PPTX
Oer slides fall 2013
WayneSmith
 
PDF
Guida Ebooks & iBooks Author
Artlandis' Webinar & Workshop
 
PPTX
Geotrails
Leisure Solutions®
 
PPT
Pubcon 2013 - Post mortem banned site forensics
Brian McDowell
 
PDF
Iii jal pres_avaluaciocompetencial
Arnau Cerdà
 
PPT
Smart Questions
Business Book Summaries
 
PPTX
How to run asp.net on virtual server for $5 per mo
Yuriy Silvestrov
 
DOC
HOT N´COLD
Sonia
 
PDF
Freelance Robotics Company Profile V1 2
William Pagnon
 
PDF
Digital Mediaina state
Sales Hub Pro
 
2011 some photos
Dirval Chareti
 
Hoboes Expo2
guest293db1
 
Candidiasis invasiva
Alex Castañeda-Sabogal
 
Ogc in arc_gis_g_tstyle
Gert-Jan
 
¿Tratamiento antirretroviral como prevencion?
Alex Castañeda-Sabogal
 
Tb XDR in South Africa
Alex Castañeda-Sabogal
 
Oer slides fall 2013
WayneSmith
 
Guida Ebooks & iBooks Author
Artlandis' Webinar & Workshop
 
Pubcon 2013 - Post mortem banned site forensics
Brian McDowell
 
Iii jal pres_avaluaciocompetencial
Arnau Cerdà
 
Smart Questions
Business Book Summaries
 
How to run asp.net on virtual server for $5 per mo
Yuriy Silvestrov
 
HOT N´COLD
Sonia
 
Freelance Robotics Company Profile V1 2
William Pagnon
 
Digital Mediaina state
Sales Hub Pro
 
Ad

Similar to Metaprogramming + Ds Ls (20)

KEY
Ruby
Kerry Buckley
 
PDF
Designing Ruby APIs
Wen-Tien Chang
 
PDF
Metaprogramovanie #1
Jano Suchal
 
PDF
Refactoring Workshop (Rails Pacific 2014)
Bruce Li
 
PDF
Ruby on Rails at PROMPT ISEL '11
Pedro Cunha
 
PDF
Postobjektové programovanie v Ruby
Jano Suchal
 
KEY
A tour on ruby and friends
旻琦 潘
 
PDF
Ruby - Design patterns tdc2011
Rafael Felix da Silva
 
KEY
Dsl
phoet
 
PDF
Blocks by Lachs Cox
lachie
 
PDF
Attributes Unwrapped: Lessons under the surface of active record
.toster
 
PDF
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
Tchelinux
 
PDF
Ruby Programming Language
Duda Dornelles
 
PPT
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Anton Shemerey
 
KEY
Ruby/Rails
rstankov
 
PDF
All I Need to Know I Learned by Writing My Own Web Framework
Ben Scofield
 
ZIP
Presentation.Key
guesta2b31d
 
PDF
Active Support Core Extensions (1)
RORLAB
 
PDF
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Raimonds Simanovskis
 
KEY
How To Test Everything
noelrap
 
Designing Ruby APIs
Wen-Tien Chang
 
Metaprogramovanie #1
Jano Suchal
 
Refactoring Workshop (Rails Pacific 2014)
Bruce Li
 
Ruby on Rails at PROMPT ISEL '11
Pedro Cunha
 
Postobjektové programovanie v Ruby
Jano Suchal
 
A tour on ruby and friends
旻琦 潘
 
Ruby - Design patterns tdc2011
Rafael Felix da Silva
 
Dsl
phoet
 
Blocks by Lachs Cox
lachie
 
Attributes Unwrapped: Lessons under the surface of active record
.toster
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
Tchelinux
 
Ruby Programming Language
Duda Dornelles
 
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Anton Shemerey
 
Ruby/Rails
rstankov
 
All I Need to Know I Learned by Writing My Own Web Framework
Ben Scofield
 
Presentation.Key
guesta2b31d
 
Active Support Core Extensions (1)
RORLAB
 
Rails-like JavaScript using CoffeeScript, Backbone.js and Jasmine
Raimonds Simanovskis
 
How To Test Everything
noelrap
 

More from ArrrrCamp (15)

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

Recently uploaded (20)

PDF
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
PDF
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
PDF
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
AbdullahSani29
 
PDF
CIFDAQ's Token Spotlight: SKY - A Forgotten Giant's Comeback?
CIFDAQ
 
PPTX
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 
PDF
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
 
PDF
agentic-ai-and-the-future-of-autonomous-systems.pdf
siddharthnetsavvies
 
PDF
Building High-Performance Oracle Teams: Strategic Staffing for Database Manag...
SMACT Works
 
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
AVTRON Technologies LLC
 
PDF
Doc9.....................................
SofiaCollazos
 
PDF
Revolutionize Operations with Intelligent IoT Monitoring and Control
Rejig Digital
 
PDF
The Evolution of KM Roles (Presented at Knowledge Summit Dublin 2025)
Enterprise Knowledge
 
PDF
Test Bank, Solutions for Java How to Program, An Objects-Natural Approach, 12...
famaw19526
 
PDF
CIFDAQ'S Market Insight: BTC to ETH money in motion
CIFDAQ
 
PDF
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
Captain IT
 
PDF
CIFDAQ's Teaching Thursday: Moving Averages Made Simple
CIFDAQ
 
PPTX
The Power of IoT Sensor Integration in Smart Infrastructure and Automation.pptx
Rejig Digital
 
PPTX
How to Build a Scalable Micro-Investing Platform in 2025 - A Founder’s Guide ...
Third Rock Techkno
 
PPTX
C Programming Basics concept krnppt.pptx
Karan Prajapat
 
PDF
Accelerating Oracle Database 23ai Troubleshooting with Oracle AHF Fleet Insig...
Sandesh Rao
 
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
 
NewMind AI Weekly Chronicles - July'25 - Week IV
NewMind AI
 
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
AbdullahSani29
 
CIFDAQ's Token Spotlight: SKY - A Forgotten Giant's Comeback?
CIFDAQ
 
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
 
agentic-ai-and-the-future-of-autonomous-systems.pdf
siddharthnetsavvies
 
Building High-Performance Oracle Teams: Strategic Staffing for Database Manag...
SMACT Works
 
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
AVTRON Technologies LLC
 
Doc9.....................................
SofiaCollazos
 
Revolutionize Operations with Intelligent IoT Monitoring and Control
Rejig Digital
 
The Evolution of KM Roles (Presented at Knowledge Summit Dublin 2025)
Enterprise Knowledge
 
Test Bank, Solutions for Java How to Program, An Objects-Natural Approach, 12...
famaw19526
 
CIFDAQ'S Market Insight: BTC to ETH money in motion
CIFDAQ
 
How Onsite IT Support Drives Business Efficiency, Security, and Growth.pdf
Captain IT
 
CIFDAQ's Teaching Thursday: Moving Averages Made Simple
CIFDAQ
 
The Power of IoT Sensor Integration in Smart Infrastructure and Automation.pptx
Rejig Digital
 
How to Build a Scalable Micro-Investing Platform in 2025 - A Founder’s Guide ...
Third Rock Techkno
 
C Programming Basics concept krnppt.pptx
Karan Prajapat
 
Accelerating Oracle Database 23ai Troubleshooting with Oracle AHF Fleet Insig...
Sandesh Rao
 

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/