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
Ruby Metaprogramming
Search
Sergio Gil
March 25, 2012
Programming
11
2.6k
Ruby Metaprogramming
Slides from my talk at #codemotion #es (Madrid, March 24th 2012).
http://codemotion.es/
Sergio Gil
March 25, 2012
Tweet
Share
More Decks by Sergio Gil
See All by Sergio Gil
Understanding Unix pipes with Ruby
porras
0
140
Crystal
porras
4
320
Enumerator.is_an(Enumerable) [es]
porras
0
150
5 hidden gems of the Ruby Standard Library
porras
2
190
Enumerator is an Enumerable 💃
porras
3
120
Queue and SizedQueue: hidden gems in the Ruby standard library
porras
0
170
Laziness
porras
3
220
Standing on the shoulders of giants
porras
0
210
I used to be a writer (love letter to Ruby)
porras
2
220
Other Decks in Programming
See All in Programming
Kotlin Multiplatform at Stable and Beyond (Android Makers 2024)
zsmb
0
490
Goのmultiple errorsについて (2024年4月版)
syumai
4
1.2k
CA.swift19 恋するAIアプリ開発の裏側
oskmr
0
380
AppRouter Panel Talk
yosuke_furukawa
PRO
1
470
Behind VS Code Extensions for JavaScript / TypeScript Linnting and Formatting
unvalley
6
1.2k
PostmanでAPIの動作確認が楽になった話
h455h1
0
180
Git Rebase
bkuhlmann
11
1.6k
Fast JSX: Don't clone props object #28768
yossydev
1
190
MetricKitで予期せぬ終了を検知する話 / Detect unexpected termination with MetricKit
nekowen
1
200
Try creating your own orderedmap
kazamori
1
210
Documentation for users with AsciiDoc and Antora
ahus1
0
370
Introducing Kotlin Multiplatform in an existing mobile app - Workshop Edition | AndroidMakers Paris
prof18
0
160
Featured
See All Featured
Optimizing for Happiness
mojombo
370
69k
The Cost Of JavaScript in 2023
addyosmani
20
3.9k
Pencils Down: Stop Designing & Start Developing
hursman
117
11k
Statistics for Hackers
jakevdp
790
220k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
21
1.4k
10 Git Anti Patterns You Should be Aware of
lemiorhan
649
58k
Learning to Love Humans: Emotional Interface Design
aarron
267
39k
The Language of Interfaces
destraynor
151
23k
How to name files
jennybc
65
93k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
221
21k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
18
6.9k
Adopting Sorbet at Scale
ufuk
69
8.6k
Transcript
Ruby Metaprogramming Sergio Gil (@porras)
None
require 'excel' require 'sql' Excel.load('file.xls').each do |row| SQL.insert(row) end
None
require 'html' require 'http' page = HTML.load(HTTP.get('http://example.com/')) page.links.each do |link|
HTTP.get(link).save end
class Company def projects HTTP::Request.new('/projects').get end def people HTTP::Request.new('/people').get end
def clients HTTP::Request.new('/clients').get end ... end
Yukihiro Matsumoto ‘Matz’, Ruby creator
None
Metaprogramming
defining metaprogramming
None
None
None
None
Classes Instances Methods Variables Constants Modules
Classes Instances Methods Variables Constants Modules
Memory
Classes Instances Methods Variables Constants Modules
None
>> str = "hola" => "hola"
>> str = "hola" => "hola" >> str.methods => [...,
:reverse, ...]
>> str = "hola" => "hola" >> str.methods => [...,
:reverse, ...] >> def str.reverse "adios" end
>> str = "hola" => "hola" >> str.methods => [...,
:reverse, ...] >> def str.reverse "adios" end >> str.reverse
>> str = "hola" => "hola" >> str.methods => [...,
:reverse, ...] >> def str.reverse "adios" end >> str.reverse => "adios"
Ruby Object Model: The Musical
None
None
None
None
None
It’s all about DRYness
class Company def projects HTTP::Request.new('/projects').get end def people HTTP::Request.new('/people').get end
... end
class Company def projects get('/projects') end def people get('/people') end
... private def get(url) HTTP::Request.new(url).get end end
Is that all?
Let Ruby create your methods for you
class Company [:projects, :people, ...].each do |method| eval %Q{ def
#{method} HTTP::Request.new('/#{method}').get end } end end
class Company [:projects, :people, ...].each do |method| define_method method do
HTTP::Request.new("/#{method}").get end end end
None
It’s all about expresivity
None
module HTTP def get(*methods) methods.each do |method| define_method method do
HTTP::Request.new("/#{method}").get end end end end
module HTTP def get(*methods) methods.each do |method| define_method method do
HTTP::Request.new("/#{method}").get end end end end class Company extend HTTP get :projects, :people, ... end
“I Taw a Putty DSL...”
class Company extend HTTP get :projects, :people, ... end
It’s all about flexibility
class Company def method_missing(method, *args, &blk) HTTP::Request.new("/#{method}").get end end
class Company def method_missing(method, *args, &blk) HTTP::Request.new("/#{method}").get end end
It’s all common sense
metaprogramming == programming
same trade-offs apply
None
None
None
“Cleverness cannot win. The only weapons we have are simplicity
and convention” http://alarmingdevelopment.org/?p=422
Thank you :)