Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Metaprogramming ruby
Search
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
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
290
技術的負債を組織課題として解く-増えすぎたマイクロサービスとの戦い-
reimaru
1
2k
モジュールの視点からSwiftを読み解く #iosdc
s_shimotori
0
180
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
180
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
0
1.5k
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
250
AWS DevOps Agentで インシデント対応をAIに任せたい
honmarkhunt
7
3k
AI Agent時代のリアーキテクチャ戦略と実践
hokaccha
9
4.8k
SONY CISC-NEWS NWS-1750 + NWB-225 フレームバッファの NetBSD/news68k ドライバ実装 / OSC2026Hiroshima
tsutsui
0
120
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
7.4k
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
4
2.7k
What We Talk About When We Talk About XP
m_seki
2
660
Featured
See All Featured
How Software Deployment tools have changed in the past 20 years
geshan
1
34k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.7k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.2k
Tell your own story through comics
letsgokoyo
1
1.1k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
We Have a Design System, Now What?
morganepeng
55
8.3k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Navigating Weather and Climate Data
rabernat
0
520
4 Signs Your Business is Dying
shpigford
187
23k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
570
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
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