Generative Artificial Intelligence: How generative AI works.pdf
Metaprogramming in Ruby
1. Introduction
DSL implementation
Summary
Metaprogramming in Ruby
Domain specific languages
Peter Vanbroekhoven
peter@xaop.com
BRUG meeting October 3 2007
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
2. Introduction
DSL implementation
Summary
Outline
Introduction
1
Metaprogramming
Ruby and Metaprogramming
DSL implementation
2
Changing self
Missing constants
Missing methods
Implementing custom operators
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
3. Introduction
DSL implementation
Summary
Outline
Introduction
1
Metaprogramming
Ruby and Metaprogramming
DSL implementation
2
Changing self
Missing constants
Missing methods
Implementing custom operators
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
4. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Outline
Introduction
1
Metaprogramming
Ruby and Metaprogramming
DSL implementation
2
Changing self
Missing constants
Missing methods
Implementing custom operators
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
5. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
What Is Metaprogramming?
Programming
your
programming
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
6. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
What Is Metaprogramming?
Metaprogramming
is a
good thing
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
7. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
The Deal With Metaprogramming
class ActiveRecord : : Base
def r e a d _ a t t r i b u t e ( attr_name )
@ a t t r i b u t e s [ attr_name ]
end
end
class MicrosoftCEO < ActiveRecord : : Base
end
b i l l = MicrosoftCEO . new
my_pocket << b i l l . r e a d _ a t t r i b u t e ( quot; money quot; )
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
8. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
The Deal With Metaprogramming
class MicrosoftCEO < ActiveRecord : : Base
def money
@ a t t r i b u t e s [ quot; money quot; ]
end
end
b i l l = MicrosoftCEO . new
my_pocket << b i l l . money
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
9. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
The Deal With Metaprogramming
class MicrosoftCEO < ActiveRecord : : Base
def money
@ a t t r i b u t e s [ quot; money quot; ]
end
def house
@ a t t r i b u t e s [ quot; house quot; ]
end
def c a r
@attributes [ quot; car quot; ]
end
end
b i l l = MicrosoftCEO . new
my_pocket << b i l l . money << b i l l . house << b i l l . c a r
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
10. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
The Deal With Metaprogramming
class MicrosoftCEO < ActiveRecord : : Base
[ quot; money quot; , quot; house quot; , quot; c a r quot; ] . each do | f |
define_method ( f ) { @ a t t r i b u t e s [ f ] }
end
end
b i l l = MicrosoftCEO . new
my_pocket << b i l l . money << b i l l . house << b i l l . c a r
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
11. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Examples of metaprogramming
Java compiler
Ruby interpreter
Firefox browser
Ruby on Rails
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
12. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Examples of metaprogramming
Java compiler
Ruby interpreter
Firefox browser
Ruby on Rails
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
13. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Examples of metaprogramming
Java compiler
Ruby interpreter
Firefox browser
Ruby on Rails
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
14. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Examples of metaprogramming
Java compiler
Ruby interpreter
Firefox browser
Ruby on Rails
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
15. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Examples of metaprogramming
Java compiler
Ruby interpreter
Firefox browser
Ruby on Rails
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
16. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
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 == ?_
end
def 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 e n g t h
s 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 += 1
i += 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 a t ! = i
end ; i += 1 ; end
r e s u l t ; end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
17. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Domain specific languages
def f i n d _ e m a i l s ( s t r )
s t r . scan ( / w+@ w+ / )
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
18. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Domain specific languages
DSLs
are
everywhere
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
19. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Domain specific languages
musical notes
PP PPP
PPP
PPP
P'
DSLs
are
everywhere
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
20. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Domain specific languages
guitar chords
musical notes
PP
oo
PPP
ooo
PPP
ooo
PPP o
wooo
P'
DSLs
are
everywhere
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
21. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Domain specific languages
guitar chords
musical notes
PP
oo
PPP
ooo
PPP
ooo
PPP o
wooo
P'
DSLs
are
everywhere
7
nnn
nn
nnn
nnn
n
traffic signs
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
22. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Domain specific languages
guitar chords
musical notes
PP
oo
PPP
ooo
PPP
ooo
PPP o
wooo
P'
DSLs
are
everywhereOOO
gO
7
nnn OOO
nn
nnn OOO
nnn OO
n
Ruby
traffic signs
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
23. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Outline
Introduction
1
Metaprogramming
Ruby and Metaprogramming
DSL implementation
2
Changing self
Missing constants
Missing methods
Implementing custom operators
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
24. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Metaprogramming in Java
public P l u g i n c r e a t e _ p l u g i n ( S t r i n g name ,
S t r i n g [ ] keys , S t r i n g [ ] v a l u e s )
throws . . . {
Class c = Class . forName ( name ) ;
Class s = Class . forName ( quot; [ L j a v a . l a n g . S t r i n g ; quot; ) ;
C o n s t r u c t o r co = c . g e t C o n s t r u c t o r ( s , s ) ;
r e t u r n ( P l u g i n ) co . newInstance ( keys , v a l u e s ) ;
}
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
25. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Metaprogramming in Ruby
def c r e a t e _ p l u g i n ( name , keys , v a l u e s )
O b j e c t . c o n s t _ g e t ( name ) . new ( keys , v a l u e s )
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
26. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Comparison
Metaprogramming in Ruby
is
easy
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
27. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
Comparison
Metaprogramming in Java
is
hard
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
28. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
DSLs in Ruby
f i r s t 1 , f i r s t 2 , l a s t = ’ p e t e r ’ , ’ glenn ’ , ’ v% ’
banks = c o n n e c t i o n . execute ( quot;
SELECT b . name
FROM customer AS c , bank AS b , account AS a
WHERE ( c . f i r s t n a m e = ’ #{first1} ’ OR
c . f i r s t n a m e = ’ #{first2} ’ ) AND
c . lastname LIKE ’ #{last} ’ AND
a . owner = c . i d AND
a . bank = b . i d
quot;)
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
29. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
DSLs in Ruby : ActiveRecord
Bank . f i n d (
: all ,
: i n c l u d e => { : accounts => : customer } ,
: c o n d i t i o n s => [
quot; ( customers . f i r s t _ n a m e = ? OR
customers . f i r s t _ n a m e = ? ) AND
customers . last_name LIKE ? quot; ,
quot; first1 quot; , quot; first2 quot; , quot; last quot; ]
) . map { | b | b . name }
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
30. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
DSLs in Ruby : my own DSL
f i r s t 1 , f i r s t 2 , l a s t = ’ p e t e r ’ , ’ glenn ’ , / Av /
banks = query do
from : c => Customer , : b => Bank , : a => Account
s e l e c t b . name
where ( ( c . f i r s t n a m e == f i r s t 1 ) |
( c . f i r s t n a m e == f i r s t 2 ) ) &
( c . lastname =~ l a s t ) &
( a . owner == c ) &
( a . bank == b )
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
31. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
DSLs in Ruby : my own DSL
f i r s t 1 , f i r s t 2 , l a s t = ’ p e t e r ’ , ’ glenn ’ , / Av /
banks = query do
from : a => Account
s e l e c t a . bank . name
where ( ( a . owner . f i r s t n a m e == f i r s t 1 ) |
( a . owner . f i r s t n a m e == f i r s t 2 ) ) &
( a . owner . lastname =~ l a s t )
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
32. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
DSLs in Ruby : my own DSL
f i r s t 1 , f i r s t 2 , l a s t = ’ p e t e r ’ , ’ glenn ’ , / Av /
banks = query do
from : a => Account
c = a . owner
s e l e c t a . bank . name
where ( ( c . f i r s t n a m e == f i r s t 1 ) |
( c . f i r s t n a m e == f i r s t 2 ) ) &
( c . lastname =~ l a s t )
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
33. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
DSLs in Ruby
A Ruby DSL
is just
plain Ruby
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
34. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
DSLs in Ruby
easy to build
O OOO
OOO
OOO
O'
A Ruby DSL
is just
plain Ruby
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
35. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
DSLs in Ruby
easy to build familiar syntax
O OOO n
nnn
OOO
nnn
OOO nn
wnnn
O'
A Ruby DSL
is just
plain Ruby
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
36. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
DSLs in Ruby
easy to build familiar syntax
O OOO n
nnn
OOO
nnn
OOO nn
wnnn
O'
A Ruby DSL
is just
plain O Ruby
abstraction
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
37. Introduction
Metaprogramming
DSL implementation
Ruby and Metaprogramming
Summary
What I’ll Teach You
f i r s t 1 , f i r s t 2 , l a s t = ’ p e t e r ’ , ’ glenn ’ , / Av /
banks = query do
from : c => Customer , : b => Bank , : a => Account
s e l e c t b . name
where ( ( c . f i r s t n a m e == f i r s t 1 ) |
( c . f i r s t n a m e == f i r s t 2 ) ) &
( c . lastname =~ l a s t ) &
( a . owner == c ) &
( a . bank == b )
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
39. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
What is self?
self
is the
current object
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
40. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
What is self?
instance
variables OO
OOO
OOO
OOO
'
self
is the
current object
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
41. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
What is self?
instance dotless
variables OO methods
n
OOO n
nnn
OOO
nnn
OOO
vnnn
'
self
is the
current object
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
42. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
What is self?
instance dotless
variables OO methods
n
OOO n
nnn
OOO
nnn
OOO
vnnn
'
self
is the
current object
8
qqq
q
qqq
qqq
qq
class
variables
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
43. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
What is self?
instance dotless
variables OO methods
n
OOO n
nnn
OOO
nnn
OOO
vnnn
'
self
is the
current object
8 gOOO
qqq O OOO
q
qqq OOO
qqq O
qq changed by
class
method calls,
variables
class defs
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
44. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
What is self?
banks = query do
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
45. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
What is self?
banks = s e l f . query do
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
46. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
What is self?
# Top l e v e l
p self # => main
p s e l f . class # => O b j e c t
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
47. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
What is self?
banks = s e l f . query do
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
48. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
The Kernel module
Kernel
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
49. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
The Kernel module
puts O
OOO
OOO
OOO
O'
Kernel
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
50. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
The Kernel module
puts O raise
OOO qqq
OOO qqq
OOO qq
xqqq
O'
Kernel
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
51. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
The Kernel module
puts O raise
OOO qqq
OOO qqq
OOO qq
xqqq
O'
Kernel
oo7
ooo
ooo
ooo
require
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
52. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
The Kernel module
puts O raise
OOO qqq
OOO qqq
OOO qq
xqqq
O'
KernelMM
fMMM
oo7
ooo M
ooo MMM
ooo MM
require eval
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
53. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
The query method
module K e r n e l
def query
yield # C a l l the block
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
54. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Changing self
banks = query do
from : c => Customer , : b => Bank , : a => Account
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
55. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Changing self
banks = query do
s e l f . from : c => Customer , ...
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
56. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Changing self
banks = query do
p s e l f # => main
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
57. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Changing self
banks = query do
s e l f . from : c => Customer , ...
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
58. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Changing self
Sometimes
we want to
change self
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
59. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Changing self
class Query
end
module K e r n e l
def query (& b l k )
Query . new . i n s t a n c e _ e v a l (& b l k )
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
60. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Changing self
banks = query do
p s e l f # => #<Query : 0 xb7cc4adc >
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
61. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Changing self
instance_eval
changes self
for the duration of a block
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
62. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Changing self
class Query
def i n i t i a l i z e
@from = { }
end
def from (map)
@from = map
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
63. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Changing self
banks = query do
from : c => Customer , : b => Bank , : a => Account
p s e l f # => #<Query : 0 xb7cc4adc
# @from = { : b=>Bank , : a=>Account , : c=>Customer } >
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
65. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Lazy class loading
Rails
can do
lazy class loading
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
66. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Lazy class loading
test.rb
# r e q u i r e ’ brug ’
BRUG. new ( Time . now )
brug.rb
class BRUG
def i n i t i a l i z e ( t i m e )
@time = t i m e
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
68. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Constant lookup
BRUG.new
n = Module.nesting + [Object]
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
69. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Constant lookup
BRUG.new
n = Module.nesting + [Object]
find BRUG in n
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
70. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Constant lookup
BRUG.new
n = Module.nesting + [Object]
find BRUG in n
u
u
uu
uu
u
founduuu
uu
uu
uu
uu
zuu
return BRUG
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
71. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Constant lookup
BRUG.new
n = Module.nesting + [Object]
u KK
find BRUGKin n
u KK
uu KK
uu KK
u
founduuu KK found
not
KK
uu KK
uu KK
uu KK
uu KK
zuu %
n [0]. const_missing(:BRUG)
return BRUG
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
72. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Module.nesting
class A
module B
def m
Module . n e s t i n g # = [ A : : B , A ]
end
Module . n e s t i n g # = [ A : : B , A ]
end
end
Module . n e s t i n g # = [ ]
def A .m
Module . n e s t i n g # = [ ]
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
73. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Lazy class loading
banks = query do
from : c = Customer , : b = Bank , : a = Account
p Module . n e s t i n g + [ O b j e c t ] # = [ O b j e c t ]
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
74. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Lazy loading
def O b j e c t . c o n s t _ m i s s i n g ( c i d )
f i l e = f i n d _ f i l e ( cid )
require f i l e
const_get ( cid )
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
75. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Lazy class loading
def O b j e c t . c o n s t _ m i s s i n g ( c i d )
f i l e = f i n d _ f i l e ( cid )
require f i l e
i f const_defined? cid
const_get ( cid )
else
# c a l l old const_missing
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
76. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Lazy class loading
def O b j e c t . c o n s t _ m i s s i n g ( c i d )
f i l e = f i n d _ f i l e ( cid )
require f i l e
i f const_defined? cid
const_get ( cid )
else
# Class Module
super
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
77. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Lazy class loading
Lazy class loading
is
freakingly easy
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
79. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Handling b.name
banks = query do
...
s e l e c t b . name
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
80. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Handling b.name
banks = query do
...
s e l e c t s e l f . b . name
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
81. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Handling b.name
class Query
def b
...
end
end
banks = query do
...
s e l e c t s e l f . b . name
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
82. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Handling b.name
Can we
avoid
mass method definition
?
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
84. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Missing methods
self .b.name
ww
ww
ww
b foundwww
w
ww
ww
w
ww
{ww
self .b.name
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
85. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Missing methods
self .b.name
J JJ
ww JJ
ww JJ
ww JJ
b foundwww J
bJnot found
w JJ
ww JJ
ww JJ
w JJ
ww J$
{ww
self .method_missing(:b)
self .b.name
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
86. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Implementing Query#method_missing
banks = query do
...
p s e l f # = #Query : 0 xb7cf5dd4
s e l e c t s e l f . b . name
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
87. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Implementing Query#method_missing
class Query
def method_missing ( mid , ∗ args )
i f args . l e n g t h == 0 @from [m]
V a r i a b l e E x p r e s s i o n . new (m)
else
super
end
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
88. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Implementing Query#method_missing
class V a r i a b l e E x p r e s s i o n 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 peter@xaop.com Metaprogramming in Ruby
89. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Alternative implementation
class Query
a l i a s old_mm method_missing
def method_missing (m, ∗ args )
i f args . l e n g t h == 0 @from [m]
V a r i a b l e E x p r e s s i o n . new (m)
else
old_mm (m, ∗ args )
end
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
90. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Implementing Expression#method_missing
banks = query do
...
# select b
s e l e c t b . name
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
91. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Implementing Expression#method_missing
class Expression
def method_missing (m, ∗ args )
i f args . l e n g t h == 0
F i e l d E x p r e s s i o n . new ( s e l f , m)
else
super
end
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
92. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Implementing Expression#method_missing
class F i e l d E x p r e s s i o n Expression
def i n i t i a l i z e ( expression , f i e l d )
@expression , @ f i e l d = expression , f i e l d
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
93. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Summary
YES,
we can
avoid
mass method definition
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
95. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Oerator overloading
banks = query do
...
where ( ( c . f i r s t n a m e == f i r s t 1 ) |
( c . f i r s t n a m e == f i r s t 2 ) )
( c . lastname =~ l a s t )
( a . owner == c )
( a . bank == b )
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
96. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Operator overloading
Operators
are just
methods
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
97. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Operator overloading
banks = query do
...
where ( ( c . f i r s t n a m e . = = ( f i r s t 1 ) . | (
c . firstname .==( f i r s t 2 ) ) . (
c . lastname . = ~ ( l a s t ) . (
a . owner == c ) . ( a . bank . = = ( b ) )
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
98. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Implementing operator overloading
class Expression
def ==( o t h e r )
BinaryOpExpression . new ( s e l f , o t h e r , ’= ’ )
end
def ( o t h e r )
BinaryOpExpression . new ( s e l f , o t h e r , ’AND ’ )
end
...
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
99. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing 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 peter@xaop.com Metaprogramming in Ruby
100. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Limitations operator overloading
, ||, !
are
NOT
methods
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
101. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Summary
but ...
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
102. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Limitations operator overloading
Operator overloading
is
child’s play
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
103. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Wrapping up the example
banks = query do
...
where . . .
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
104. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Wrapping up the example
class Query
def where ( cond )
@where = cond
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
105. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Wrapping up the example
class Query
def t o _ s q l
quot;SELECT # { r e t u r n _ l i s t } quot;
quot;FROM # { t a b l e _ l i s t } quot;
quot;WHERE # { c o n d i t i o n _ e x p r } quot;
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
106. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Wrapping up the example
class Query
def t a b l e _ l i s t
@from . map { | v , t | quot; # { t } AS # { v } quot; } . j o i n ( quot; , quot; )
end
def r e t u r n _ l i s t
@select . map { | r | r . t o _ s q l } . j o i n ( quot; , quot; )
end
def c o n d i t i o n _ e x p r
@where . t o _ s q l
end
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
107. Changing self
Introduction
Missing constants
DSL implementation
Missing methods
Summary
Implementing custom operators
Wrapping up the example
f i r s t 1 , f i r s t 2 , l a s t = ’ p e t e r ’ , ’ glenn ’ , / Av /
banks = query do
from : c = Customer , : b = Bank , : a = Account
s e l e c t b . name
where ( ( c . f i r s t n a m e == f i r s t 1 ) |
( c . f i r s t n a m e == f i r s t 2 ) )
( c . lastname =~ l a s t )
( a . owner == c )
( a . bank == b )
end
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
108. Introduction
DSL implementation
Summary
Summary
Ruby has very natural metaprogramming facilities
Ruby allows building DSLs in pure Ruby
Metaporgramming made easy
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
109. Introduction
DSL implementation
Summary
Summary
Ruby has very natural metaprogramming facilities
Ruby allows building DSLs in pure Ruby
Metaporgramming made easy
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
110. Introduction
DSL implementation
Summary
Summary
Ruby has very natural metaprogramming facilities
Ruby allows building DSLs in pure Ruby
Metaporgramming made easy
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
111. Introduction
DSL implementation
Summary
Further reading
why’s (poignant) guide to Ruby
http://poignantguide.net/ruby/
http://poignantguide.net/ruby/chapter-6.html
Ruby for Rails
http://www.manning.com/black/
Programming Ruby
http://www.rubycentral.com/pickaxe/
http://www.pragmaticprogrammer.com/title/ruby/
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
112. Introduction
DSL implementation
Summary
Further reading
why’s (poignant) guide to Ruby
http://poignantguide.net/ruby/
http://poignantguide.net/ruby/chapter-6.html
Ruby for Rails
http://www.manning.com/black/
Programming Ruby
http://www.rubycentral.com/pickaxe/
http://www.pragmaticprogrammer.com/title/ruby/
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
113. Introduction
DSL implementation
Summary
Further reading
why’s (poignant) guide to Ruby
http://poignantguide.net/ruby/
http://poignantguide.net/ruby/chapter-6.html
Ruby for Rails
http://www.manning.com/black/
Programming Ruby
http://www.rubycentral.com/pickaxe/
http://www.pragmaticprogrammer.com/title/ruby/
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby
114. Introduction
DSL implementation
Summary
REAL Summary
Ruby rocks!!!
Peter Vanbroekhoven peter@xaop.com Metaprogramming in Ruby