Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Metaprogramming ruby
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Abhaya Thapa
October 01, 2012
Programming
200
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Metaprogramming ruby
metaprogramming dsl ruby
Abhaya Thapa
October 01, 2012
More Decks by Abhaya Thapa
See All by Abhaya Thapa
Top 10 algorithms of 20th century
abhayathapa
2
460
Python Idealogies
abhayathapa
8
500
Jquery Cheatsheet
abhayathapa
10
460
Django cheatsheet
abhayathapa
10
600
Other Decks in Programming
See All in Programming
20260722_microCMSで考える、AI時代のコンテンツ運用設計
yosh1
0
440
Go を使い始めて 2 ヶ月の学び / My first two months with Go
contour_gara
0
330
FastAPI の並行処理モデルを完全に理解する
hoto17296
4
1.5k
30年振りにコンパイラの定数整数除算を改善した
herumi
3
870
in-process GraphQL のすすめ #ginzajs
izumin5210
4
1.4k
仕様駆動開発の消費期限
watany
20
8.8k
書籍「プロフェッショナルAI駆動開発」紹介スライド
juntaromatsumoto
0
250
言葉の格闘技のススメ~紙とペンと言葉から始める、キャリアの描き方~
progresscicada
2
170
Oxlintはいいぞ(続)
yug1224
1
300
源内ハンズオン概要編
hideg
0
200
What's New in Android 2026
veronikapj
0
270
AIを紡ぐPMのお話
swdtkuy
0
120
Featured
See All Featured
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
Google's AI Overviews - The New Search
badams
0
1.1k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.4k
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
490
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
480
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
580
Visualization
eitanlees
152
17k
GitHub's CSS Performance
jonrohan
1033
470k
How to train your dragon (web standard)
notwaldorf
97
6.8k
The browser strikes back
jonoalderson
0
1.5k
Transcript
Metaprogramming Ruby - What the hell's a DSL? • murphee
(Werner Schuster) • Blog @ http://jroller.com/page/murphee
Meta?
Programs that write Programs
Compiler
DSLs
Regexes, anyone?
Always good to start with quotes by...
Alan Kay
The general attitude seems to be that people should wear
square shoes, because squares are easier to design and manufacture than foot shaped shoes. ...
If the shoe industry has gone the way of the
computer industry it would now be running a $200-a- day course on how to walk, run and jump in square shoes." Alan Kay
DSLs • Internal – use host language • External –
Yacc, ANTLR, ...
Executable Spec
Let's start with... Dylan • http://www.networknightvision.com/ • Dylan • declarative
protocol spec
Ethernet spec in Dylan define protocol ethernet−frame ( header−frame )
summary ”ETH %= −> %=/%s ” , source−address , destination−address , compose ( summary , payload ) ; field destination−address : : <mac−address >; field source−address : : <mac−address >; field type−code : : <2byte−big−endian−unsigned−integer >; var iably−typed−field payload , type−function: select ( frame . type−code ) #x800 => <ipv4−frame >; #x806 => <arp−frame >; otherwise => <raw−frame >; end ; end ;
Ethernet spec in Dylan define protocol ethernet−frame ( header−frame )
summary ”ETH %= −> %=/%s ” , source−address , destination−address , compose ( summary , payload ) ; field destination−address : : <mac−address >; field source−address : : <mac−address >; field type−code : : <2byte−big−endian−unsigned−integer >; var iably−typed−field payload , type−function: select ( frame . type−code ) #x800 => <ipv4−frame >; #x806 => <arp−frame >; otherwise => <raw−frame >; end ; end ;
Ethernet spec in Dylan define protocol ethernet−frame ( header−frame )
summary ”ETH %= −> %=/%s ” , source−address , destination−address , compose ( summary , payload ) ; field destination−address : : <mac−address >; field source−address : : <mac−address >; field type−code : : <2byte−big−endian−unsigned−integer >; var iably−typed−field payload , type−function: select ( frame . type−code ) #x800 => <ipv4−frame >; #x806 => <arp−frame >; otherwise => <raw−frame >; end ; end ;
Design Process
Incremental does it • Sketching • Make it work •
? • Profit!
Example time • http://www.infoq.com/articles/propertiesmetaprogramming
Properties in Ruby/1 • C#-like Properties in Ruby • Why?
– to piss of Java zealots
Properties in Ruby/2 - Sketching class Foo property name end
Properties in Ruby/2 - Sketching class Foo property name end
NameError: undefined local variable or method `name' for main:Object
Properties in Ruby/3 - Fix class Foo property :name end
Properties in Ruby/3 - Fix class Foo property :name end
NameError: undefined method `property' for main:Object
Properties in Ruby/3 - Fix def property(sym) ... end class
Foo property :name end
Properties in Ruby/3 - Fix def property(sym) define_method("#{sym}=") do |value|
instance_variable_set("@#{sym}", value) end end class Foo property :name end
Properties in Ruby/3 - Fix def property(sym) define_method("#{sym}=") do |value|
instance_variable_set("@#{sym}", value) end end class Foo property :name end name=
Properties in Ruby/3 - Fix def property(sym) define_method("#{sym}=") do |value|
instance_variable_set("@#{sym}", value) end end class Foo property :name end @name
Properties in Ruby/4 - Expand def property(*sym, &bl) # Code:
Homework define_method("#{sym}=") do |value| # More Homework instance_variable_set("@#{sym}", value) end end class Tower property(:width, :height) {|val| val > 200} end
What we know by now • Class definitions are executed
• Symbols are nice • Blocks too
Another one
Pattern Matching
Parseweasel
Ruby ParseTree foo.hello(1)
Ruby ParseTree foo.hello(1) > [:vcall, :hello, :foo, [:args, [:lit, 1]
] ]
Ruby ParseTree foo.hello(1) > [:vcall, :hello, :foo, [:args, [:lit, 1]
] ] AST as: sexpr symbolic expression
ParseWeasel pattern [:vcall, :name_, :recv_, :args_]
ParseWeasel pattern [:vcall, :name_,:recv_, :args_] someone.something foo.bar murphee.speak
ParseWeasel pattern/2 [:vcall, :hello,:recv_, :args_]
ParseWeasel pattern/2 [:vcall, :hello,:recv_, :args_] foo.bar foo.hello huey().lewey().hello() huey().speak
ParseWeasel handlers handler([:vcall, :hello,:recv_, :args_]){|s| puts “Found a hello #{s[:recv]}”
}
ParseWeasel use case: optimizer replace([:call, :op_, :*, [:lit, 0] ]){|s|
[:lit, 0] }
ParseWeasel use case: optimizer replace([:call, :op_, :*, [:lit, 0] ]){|s|
[:lit, 0] } x = foo * 0
Ruby DSLs • Keep it simple • Stick to basics
• If it limps like a hack – it probably is one
Let's push it further
Let's mess up the syntax
Hello LISP (defun factorial (x) (if (zerop x) 1 (*
x (factorial ( x 1))) ) ) (factorial 42)
Macros
C Preprocessor
C Preprocessor
LISP Macro example: Infix (* a 42)
I want my infix!
LISP Macro example: Infix (infix (a * 42) ) what
I write
LISP Macro example: Infix (defmacro infix (one op two &rest
body) `(,op ,one ,two ) ) (infix (a * 42) ) what I write
LISP Macro example: Infix (defmacro infix (one op two &rest
body) `(,op ,one ,two ) ) (infix (a * 42) ) (* a 42) what I write what gets executed
LISP Macro: real use cases • Practical Lisp – MP3
binary parser – executable spec • Many LISP control structures
Macros in the real world • Mathematica – D[x ^
2] – Integrate[x ^ 3] – Expand[ x ^ 42] – • Macro-like • “FullForm” ~ s-expr – 3x -> Times[3, x ]
Let's wrap up • Practical Lisp – http://www.gigamonkeys.com/book/ • http://ola-bini.blogspot.com/2006/09/ruby-metaprogramming-techniques.html
• http://www.infoq.com/articles/properties-metaprogramming