Metaprogramming in Ruby
-
Upload
ross-lawley -
Category
Technology
-
view
2.120 -
download
2
description
Transcript of Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Metaprogramming in RubyDomain specific languages
Peter [email protected]
BRUG meeting October 3 2007
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Outline
1 IntroductionMetaprogrammingRuby and Metaprogramming
2 DSL implementationChanging selfMissing constantsMissing methodsImplementing custom operators
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Outline
1 IntroductionMetaprogrammingRuby and Metaprogramming
2 DSL implementationChanging selfMissing constantsMissing methodsImplementing custom operators
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Outline
1 IntroductionMetaprogrammingRuby and Metaprogramming
2 DSL implementationChanging selfMissing constantsMissing methodsImplementing custom operators
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
What Is Metaprogramming?
Programmingyour
programming
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
What Is Metaprogramming?
Metaprogrammingis a
good thing
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
The Deal With Metaprogramming
class ActiveRecord : : Basedef r e a d _ a t t r i b u t e ( attr_name )
@at t r ibu tes [ attr_name ]end
endclass MicrosoftCEO < ActiveRecord : : Baseend
b i l l = MicrosoftCEO . newmy_pocket << b i l l . r e a d _ a t t r i b u t e ( "money" )
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
The Deal With Metaprogramming
class MicrosoftCEO < ActiveRecord : : Basedef money
@at t r ibu tes [ "money" ]end
end
b i l l = MicrosoftCEO . newmy_pocket << b i l l . money
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
The Deal With Metaprogramming
class MicrosoftCEO < ActiveRecord : : Basedef money
@at t r ibu tes [ "money" ]enddef house
@at t r ibu tes [ " house " ]enddef car
@at t r ibu tes [ " car " ]end
end
b i l l = MicrosoftCEO . newmy_pocket << b i l l . money << b i l l . house << b i l l . car
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
The Deal With Metaprogramming
class MicrosoftCEO < ActiveRecord : : Base[ "money" , " house " , " car " ] . each do | f |
define_method ( f ) { @at t r ibu tes [ f ] }end
end
b i l l = MicrosoftCEO . newmy_pocket << b i l l . money << b i l l . house << b i l l . car
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Examples of metaprogramming
Java compilerRuby interpreterFirefox browserRuby on Rails
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Examples of metaprogramming
Java compilerRuby interpreterFirefox browserRuby on Rails
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Examples of metaprogramming
Java compilerRuby interpreterFirefox browserRuby on Rails
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Examples of metaprogramming
Java compilerRuby interpreterFirefox browserRuby on Rails
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Examples of metaprogramming
Java compilerRuby interpreterFirefox browserRuby on Rails
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Domain specific languages
def i s _ s t u f f _ c h a r ( c )( c >= ?a && c <= ?z ) | | ( c >= ?A && c <= ?Z) | |( c >= ?0 && c <= ?9) | | c == ?_
enddef f i n d _ s t u f f ( s t r )
r e s u l t = [ ] ; i = 0 ; while i < s t r . l eng ths t a r t = i ; i += 1 while i s _ s t u f f _ c h a r ( s t r [ i ] )i f s t a r t != i && s t r [ i ] == ’@’
a t = i ; i += 1i += 1 while i s _ s t u f f _ c h a r ( s t r [ i ] )r e s u l t << s t r [ s t a r t . . . i ] i f at != i
end ; i += 1 ; endr e s u l t ; end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Domain specific languages
def f i nd_ema i l s ( s t r )s t r . scan ( / \w+@\w+ / )
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Domain specific languages
musical notes guitar chords
DSLsare
everywhere
traffic signs Ruby
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Domain specific languages
musical notes
''PPPPPPPPPPPP
guitar chords
DSLsare
everywhere
traffic signs Ruby
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Domain specific languages
musical notes
''PPPPPPPPPPPP guitar chords
wwoooooooooooo
DSLsare
everywhere
traffic signs Ruby
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Domain specific languages
musical notes
''PPPPPPPPPPPP guitar chords
wwoooooooooooo
DSLsare
everywhere
traffic signs
77nnnnnnnnnnnn
Ruby
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Domain specific languages
musical notes
''PPPPPPPPPPPP guitar chords
wwoooooooooooo
DSLsare
everywhere
traffic signs
77nnnnnnnnnnnnRuby
ggOOOOOOOOOOOO
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Outline
1 IntroductionMetaprogrammingRuby and Metaprogramming
2 DSL implementationChanging selfMissing constantsMissing methodsImplementing custom operators
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Metaprogramming in Java
public Plug in c rea te_p lug in ( S t r i n g name,S t r i n g [ ] keys , S t r i n g [ ] values )
throws . . . {Class c = Class . forName (name ) ;Class s = Class . forName ( " [ L java . lang . S t r i n g ; " ) ;Const ruc tor co = c . ge tCons t ruc to r ( s , s ) ;return ( P lug in ) co . newInstance ( keys , values ) ;
}
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Metaprogramming in Ruby
def c rea te_p lug in (name, keys , values )Object . const_get (name ) . new( keys , values )
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Comparison
Metaprogramming in Rubyis
easy
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
Comparison
Metaprogramming in Javais
hard
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
DSLs in Ruby
f i r s t 1 , f i r s t 2 , l a s t = ’ pe ter ’ , ’ glenn ’ , ’ v\% ’banks = connect ion . execute ( "
SELECT b . nameFROM customer AS c , bank AS b , account AS aWHERE ( c . f i r s tname = ’#{first1} ’ OR
c . f i r s tname = ’#{first2} ’ ) ANDc . lastname LIKE ’#{last} ’ ANDa . owner = c . i d ANDa . bank = b . i d
" )
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
DSLs in Ruby : ActiveRecord
Bank . f i n d (: a l l ,: i nc lude => { : accounts => : customer } ,: cond i t i ons => [
" ( customers . f i r s t_name = ? ORcustomers . f i r s t_name = ?) AND
customers . last_name LIKE ? " ," f i r s t 1 " , " f i r s t 2 " , " l a s t " ]
) . map { | b | b . name }
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
DSLs in Ruby : my own DSL
f i r s t 1 , f i r s t 2 , l a s t = ’ pe ter ’ , ’ glenn ’ , / \ Av /banks = query do
from : c => Customer , : b => Bank , : a => Accounts e l e c t b . namewhere ( ( c . f i r s tname == f i r s t 1 ) |
( c . f i r s tname == f i r s t 2 ) ) &( c . lastname =~ l a s t ) &( a . owner == c ) &( a . bank == b )
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
DSLs in Ruby : my own DSL
f i r s t 1 , f i r s t 2 , l a s t = ’ pe ter ’ , ’ glenn ’ , / \ Av /banks = query do
from : a => Accounts e l e c t a . bank . namewhere ( ( a . owner . f i r s tname == f i r s t 1 ) |
( a . owner . f i r s tname == f i r s t 2 ) ) &( a . owner . lastname =~ l a s t )
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
DSLs in Ruby : my own DSL
f i r s t 1 , f i r s t 2 , l a s t = ’ pe ter ’ , ’ glenn ’ , / \ Av /banks = query do
from : a => Account
c = a . owner
s e l e c t a . bank . namewhere ( ( c . f i r s tname == f i r s t 1 ) |
( c . f i r s tname == f i r s t 2 ) ) &( c . lastname =~ l a s t )
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
DSLs in Ruby
easy to build familiar syntax
A Ruby DSLis just
plain Ruby
abstraction
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
DSLs in Ruby
easy to build
''OOOOOOOOOOO
familiar syntax
A Ruby DSLis just
plain Ruby
abstraction
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
DSLs in Ruby
easy to build
''OOOOOOOOOOO familiar syntax
wwnnnnnnnnnnnn
A Ruby DSLis just
plain Ruby
abstraction
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
DSLs in Ruby
easy to build
''OOOOOOOOOOO familiar syntax
wwnnnnnnnnnnnn
A Ruby DSLis just
plain Ruby
abstraction
OO
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
MetaprogrammingRuby and Metaprogramming
What I’ll Teach You
f i r s t 1 , f i r s t 2 , l a s t = ’ pe ter ’ , ’ glenn ’ , / \ Av /banks = query do
from : c => Customer , : b => Bank , : a => Accounts e l e c t b . namewhere ( ( c . f i r s tname == f i r s t 1 ) |
( c . f i r s tname == f i r s t 2 ) ) &( c . lastname =~ l a s t ) &( a . owner == c ) &( a . bank == b )
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Outline
1 IntroductionMetaprogrammingRuby and Metaprogramming
2 DSL implementationChanging selfMissing constantsMissing methodsImplementing custom operators
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
What is self?
instancevariables
dotlessmethods
selfis the
current object
classvariables
changed bymethod calls,class defs
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
What is self?
instancevariables
''OOOOOOOOOOO
dotlessmethods
selfis the
current object
classvariables
changed bymethod calls,class defs
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
What is self?
instancevariables
''OOOOOOOOOOO
dotlessmethods
vvnnnnnnnnnnn
selfis the
current object
classvariables
changed bymethod calls,class defs
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
What is self?
instancevariables
''OOOOOOOOOOO
dotlessmethods
vvnnnnnnnnnnn
selfis the
current object
classvariables
88qqqqqqqqqqqq
changed bymethod calls,class defs
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
What is self?
instancevariables
''OOOOOOOOOOO
dotlessmethods
vvnnnnnnnnnnn
selfis the
current object
classvariables
88qqqqqqqqqqqq changed bymethod calls,class defs
ggOOOOOOOOOOO
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
What is self?
banks = query do. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
What is self?
banks = se l f . query do. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
What is self?
# Top l e v e lp se l f # => mainp se l f . class # => Object
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
What is self?
banks = se l f . query do. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
The Kernel module
puts raise
Kernel
require eval
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
The Kernel module
puts
''OOOOOOOOOOO
raise
Kernel
require eval
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
The Kernel module
puts
''OOOOOOOOOOO raise
xxqqqqqqqqqqq
Kernel
require eval
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
The Kernel module
puts
''OOOOOOOOOOO raise
xxqqqqqqqqqqq
Kernelrequire
77ooooooooooo
eval
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
The Kernel module
puts
''OOOOOOOOOOO raise
xxqqqqqqqqqqq
Kernelrequire
77oooooooooooeval
ffMMMMMMMMMMM
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
The query method
module Kerneldef query
yie ld # Ca l l the blockend
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Changing self
banks = query dofrom : c => Customer , : b => Bank , : a => Account. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Changing self
banks = query dose l f . from : c => Customer , . . .. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Changing self
banks = query dop se l f # => main
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Changing self
banks = query dose l f . from : c => Customer , . . .. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Changing self
Sometimeswe want tochange self
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Changing self
class Queryendmodule Kernel
def query (& b lk )Query . new . ins tance_eva l (& b lk )
endend
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Changing self
banks = query dop se l f # => #<Query :0 xb7cc4adc>
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Changing self
instance_evalchanges self
for the duration of a block
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Changing self
class Querydef i n i t i a l i z e
@from = { }enddef from (map)
@from = mapend
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Changing self
banks = query dofrom : c => Customer , : b => Bank , : a => Accountp se l f # => #<Query :0 xb7cc4adc# @from = { : b=>Bank , : a=>Account , : c=>Customer } >
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Outline
1 IntroductionMetaprogrammingRuby and Metaprogramming
2 DSL implementationChanging selfMissing constantsMissing methodsImplementing custom operators
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Lazy class loading
Railscan do
lazy class loading
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Lazy class loading
test.rb
# requ i re ’ brug ’BRUG. new( Time . now)
brug.rb
class BRUGdef i n i t i a l i z e ( t ime )
@time = t imeend
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Constant lookup
BRUG.new
n = Module.nesting + [Object]
find BRUG in n
return BRUG n [0]. const_missing(:BRUG)
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Constant lookup
BRUG.new
��n = Module.nesting + [Object]
find BRUG in n
return BRUG n [0]. const_missing(:BRUG)
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Constant lookup
BRUG.new
��n = Module.nesting + [Object]
��find BRUG in n
return BRUG n [0]. const_missing(:BRUG)
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Constant lookup
BRUG.new
��n = Module.nesting + [Object]
��find BRUG in n
found
zzuuuuuuuuuuuuuuuuuuuu
return BRUG
n [0]. const_missing(:BRUG)
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Constant lookup
BRUG.new
��n = Module.nesting + [Object]
��find BRUG in n
found
zzuuuuuuuuuuuuuuuuuuuu
not found
%%KKKKKKKKKKKKKKKKKKKKK
return BRUG n [0]. const_missing(:BRUG)
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Module.nesting
class Amodule B
def mModule . nes t ing # => [A : : B, A ]
endModule . nes t ing # => [A : : B, A ]
endendModule . nes t ing # => [ ]def A.m
Module . nes t ing # => [ ]end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Lazy class loading
banks = query dofrom : c => Customer , : b => Bank , : a => Accountp Module . nes t ing + [ Object ] # => [ Object ]. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Lazy loading
def Object . const_missing ( c id )f i l e = f i n d _ f i l e ( c id )requ i re f i l econst_get ( c id )
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Lazy class loading
def Object . const_missing ( c id )f i l e = f i n d _ f i l e ( c id )requ i re f i l ei f const_def ined? c id
const_get ( c id )else
# c a l l o ld const_missingend
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Lazy class loading
def Object . const_missing ( c id )f i l e = f i n d _ f i l e ( c id )requ i re f i l ei f const_def ined? c id
const_get ( c id )else
# Class < Modulesuper
endend
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Lazy class loading
Lazy class loadingis
freakingly easy
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Outline
1 IntroductionMetaprogrammingRuby and Metaprogramming
2 DSL implementationChanging selfMissing constantsMissing methodsImplementing custom operators
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Handling b.name
banks = query do. . .s e l e c t b . name. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Handling b.name
banks = query do. . .s e l e c t se l f . b . name. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Handling b.name
class Querydef b
. . .end
end
banks = query do. . .s e l e c t se l f . b . name. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Handling b.name
Can we
avoidmass method definition
?
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Missing methods
self .b.name
self .b.name self .method_missing(:b)
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Missing methods
self .b.name
b found
{{wwwwwwwwwwwwwwwwwww
self .b.name
self .method_missing(:b)
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Missing methods
self .b.name
b found
{{wwwwwwwwwwwwwwwwwww
b not found
$$JJJJJJJJJJJJJJJJJJJJ
self .b.name self .method_missing(:b)
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Implementing Query#method_missing
banks = query do. . .p se l f # => #<Query :0 xb7cf5dd4 >s e l e c t se l f . b . name. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Implementing Query#method_missing
class Querydef method_missing ( mid , ∗args )
i f args . leng th == 0 && @from [m]Var iab leExpress ion . new(m)
elsesuper
endend
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Implementing Query#method_missing
class Var iab leExpress ion < Expression
a t t r _ r e a d e r : varname
def i n i t i a l i z e ( varname )@varname = varname
end
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Alternative implementation
class Querya l ias old_mm method_missingdef method_missing (m, ∗args )
i f args . leng th == 0 && @from [m]Var iab leExpress ion . new(m)
elseold_mm (m, ∗args )
endend
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Implementing Expression#method_missing
banks = query do. . .# s e l e c t bs e l e c t b . name. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Implementing Expression#method_missing
class Expression
def method_missing (m, ∗args )i f args . leng th == 0
Fie ldExpress ion . new( sel f , m)else
superend
end
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Implementing Expression#method_missing
class Fie ldExpress ion < Expressiondef i n i t i a l i z e ( expression , f i e l d )
@expression , @f ie ld = expression , f i e l dend
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Summary
YES,we can
avoidmass method definition
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Outline
1 IntroductionMetaprogrammingRuby and Metaprogramming
2 DSL implementationChanging selfMissing constantsMissing methodsImplementing custom operators
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Oerator overloading
banks = query do. . .where ( ( c . f i r s tname == f i r s t 1 ) |
( c . f i r s tname == f i r s t 2 ) ) &( c . lastname =~ l a s t ) &( a . owner == c ) &( a . bank == b )
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Operator overloading
Operatorsare just
methods
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Operator overloading
banks = query do. . .where ( ( c . f i r s tname .==( f i r s t 1 ) . | (
c . f i r s tname .==( f i r s t 2 ) ) . & (c . lastname .=~( l a s t ) . & (a . owner == c ) . & ( a . bank .==( b ) )
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Implementing operator overloading
class Expressiondef ==( o ther )
BinaryOpExpression . new( sel f , other , ’ = ’ )enddef &( other )
BinaryOpExpression . new( sel f , other , ’AND ’ )end. . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Implementing operator overloading
class BinaryOpExpression < Expression
def i n i t i a l i z e ( expr1 , expr2 , op )@expr1 , @expr2 , @op = expr1 , expr2 , op
end
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Limitations operator overloading
&&, ||, !are
NOTmethods
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Summary
but ...
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Limitations operator overloading
Operator overloadingis
child’s play
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Wrapping up the example
banks = query do. . .where . . .
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Wrapping up the example
class Query
def where ( cond )@where = cond
end
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Wrapping up the example
class Query
def t o_sq l"SELECT #{ r e t u r n _ l i s t } " \"FROM #{ t a b l e _ l i s t } " \"WHERE #{ cond i t i on_expr } "
end
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Wrapping up the example
class Querydef t a b l e _ l i s t
@from .map { | v , t | " #{ t } AS #{ v } " } . j o i n ( " , " )end
def r e t u r n _ l i s t@select .map { | r | r . t o_sq l } . j o i n ( " , " )
end
def cond i t i on_expr@where . to_sq l
endend
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Changing selfMissing constantsMissing methodsImplementing custom operators
Wrapping up the example
f i r s t 1 , f i r s t 2 , l a s t = ’ pe ter ’ , ’ glenn ’ , / \ Av /banks = query do
from : c => Customer , : b => Bank , : a => Accounts e l e c t b . namewhere ( ( c . f i r s tname == f i r s t 1 ) |
( c . f i r s tname == f i r s t 2 ) ) &( c . lastname =~ l a s t ) &( a . owner == c ) &( a . bank == b )
end
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Summary
Ruby has very natural metaprogramming facilitiesRuby allows building DSLs in pure RubyMetaporgramming made easy
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Summary
Ruby has very natural metaprogramming facilitiesRuby allows building DSLs in pure RubyMetaporgramming made easy
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Summary
Ruby has very natural metaprogramming facilitiesRuby allows building DSLs in pure RubyMetaporgramming made easy
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Further reading
why’s (poignant) guide to Rubyhttp://poignantguide.net/ruby/http://poignantguide.net/ruby/chapter-6.html
Ruby for Railshttp://www.manning.com/black/
Programming Rubyhttp://www.rubycentral.com/pickaxe/http://www.pragmaticprogrammer.com/title/ruby/
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Further reading
why’s (poignant) guide to Rubyhttp://poignantguide.net/ruby/http://poignantguide.net/ruby/chapter-6.html
Ruby for Railshttp://www.manning.com/black/
Programming Rubyhttp://www.rubycentral.com/pickaxe/http://www.pragmaticprogrammer.com/title/ruby/
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
Further reading
why’s (poignant) guide to Rubyhttp://poignantguide.net/ruby/http://poignantguide.net/ruby/chapter-6.html
Ruby for Railshttp://www.manning.com/black/
Programming Rubyhttp://www.rubycentral.com/pickaxe/http://www.pragmaticprogrammer.com/title/ruby/
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby
IntroductionDSL implementation
Summary
REAL Summary
Ruby rocks!!!
Peter Vanbroekhoven [email protected] Metaprogramming in Ruby