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.7k
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
180
Crystal
porras
4
330
Enumerator.is_an(Enumerable) [es]
porras
0
160
5 hidden gems of the Ruby Standard Library
porras
2
250
Enumerator is an Enumerable 💃
porras
3
130
Queue and SizedQueue: hidden gems in the Ruby standard library
porras
0
180
Laziness
porras
3
230
Standing on the shoulders of giants
porras
0
220
I used to be a writer (love letter to Ruby)
porras
2
240
Other Decks in Programming
See All in Programming
データの民主化を支える、透明性のあるデータ利活用への挑戦 2025-06-25 Database Engineering Meetup#7
y_ken
0
340
チームで開発し事業を加速するための"良い"設計の考え方 @ サポーターズCoLab 2025-07-08
agatan
0
120
ふつうの技術スタックでアート作品を作ってみる
akira888
0
440
“いい感じ“な定量評価を求めて - Four Keysとアウトカムの間の探求 -
nealle
1
8k
AIと”コードの評価関数”を共有する / Share the "code evaluation function" with AI
euglena1215
1
140
WindowInsetsだってテストしたい
ryunen344
1
240
PipeCDのプラグイン化で目指すところ
warashi
1
260
今ならAmazon ECSのサービス間通信をどう選ぶか / Selection of ECS Interservice Communication 2025
tkikuc
21
3.9k
Team topologies and the microservice architecture: a synergistic relationship
cer
PRO
0
1.2k
第9回 情シス転職ミートアップ 株式会社IVRy(アイブリー)の紹介
ivry_presentationmaterials
1
270
なぜ適用するか、移行して理解するClean Architecture 〜構造を超えて設計を継承する〜 / Why Apply, Migrate and Understand Clean Architecture - Inherit Design Beyond Structure
seike460
PRO
3
740
GitHub Copilot and GitHub Codespaces Hands-on
ymd65536
2
140
Featured
See All Featured
Writing Fast Ruby
sferik
628
62k
Building a Modern Day E-commerce SEO Strategy
aleyda
42
7.4k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
20k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Mobile First: as difficult as doing things right
swwweet
223
9.7k
Docker and Python
trallard
44
3.5k
Gamification - CAS2011
davidbonilla
81
5.3k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Raft: Consensus for Rubyists
vanstee
140
7k
GitHub's CSS Performance
jonrohan
1031
460k
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.6k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
5.9k
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 :)