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
This Talk is so Meta
Search
Nugroho Herucahyono
September 26, 2013
Programming
1
130
This Talk is so Meta
Introduction to metaprogramming in ruby
Nugroho Herucahyono
September 26, 2013
Tweet
Share
More Decks by Nugroho Herucahyono
See All by Nugroho Herucahyono
Simply Distributed
xinuc
0
120
Choosing the right technology
xinuc
0
180
A Tale of a Happy Programmer
xinuc
0
150
Rails on Wiradipa - Jakarta.rb Februari 2012 - Hafiz Badrie Lubiz
xinuc
1
160
Why Ruby? - View from business aspect - Jakarta.rb Februari 2012 - Fajrin Rasyid
xinuc
1
350
Other Decks in Programming
See All in Programming
XP, Testing and ninja testing ZOZ5
m_seki
3
670
Swift Concurrency - 状態監視の罠
objectiveaudio
2
520
Leading Effective Engineering Teams in the AI Era
addyosmani
5
420
Web フロントエンドエンジニアに開かれる AI Agent プロダクト開発 - Vercel AI SDK を観察して AI Agent と仲良くなろう! #FEC余熱NIGHT
izumin5210
3
530
monorepo の Go テストをはやくした〜い!~最小の依存解決への道のり~ / faster-testing-of-monorepos
convto
2
490
iOSエンジニア向けの英語学習アプリを作る!
yukawashouhei
0
200
なぜGoのジェネリクスはこの形なのか? Featherweight Goが明かす設計の核心
ryotaros
7
1.1k
Six and a half ridiculous things to do with Quarkus
hollycummins
0
170
2分台で1500examples完走!爆速CIを支える環境構築術 - Kaigi on Rails 2025
falcon8823
3
3.7k
What's new in Spring Modulith?
olivergierke
1
150
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
380
私達はmodernize packageに夢を見るか feat. go/analysis, go/ast / Go Conference 2025
kaorumuta
2
570
Featured
See All Featured
GraphQLの誤解/rethinking-graphql
sonatard
73
11k
How to train your dragon (web standard)
notwaldorf
97
6.3k
Balancing Empowerment & Direction
lara
4
690
Building a Scalable Design System with Sketch
lauravandoore
463
33k
GitHub's CSS Performance
jonrohan
1032
470k
The Invisible Side of Design
smashingmag
302
51k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
980
Statistics for Hackers
jakevdp
799
220k
Java REST API Framework Comparison - PWX 2021
mraible
34
8.9k
Unsuck your backbone
ammeep
671
58k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.2k
Context Engineering - Making Every Token Count
addyosmani
6
250
Transcript
Jakarta.rb 25 September 2013
Xinuc (Ruby) Programmer @xinuc (github, twitter) Works at Bukalapak.com Intro
We're hiring www.bukalapak.com/career Intro
This Talk is so Meta
Metaprogramming, because F*** You, That's why!
Metaprogramming: the writing of computer programs that write or manipulate
other programs (or themselves) as their data, or that do potato potato potato... Metaprogramming
Write Program that writes program (that writes program) (that writes
program) Metaprogramming
- Meet your first Meta - attr_accessor - The basic
- block - ruby class structure - method lookup - eigenclass - The technique - define_method - method_missing - method cache - class_eval - instance_eval - eval Agenda
Meet Your first meta
class Person { private String name; public String getName() {
return this.name; } public void setName(String name) { this.name = name; } } attr_accessor
class Person attr_accessor :name end attr_accessor
class Person def name @name end def name=(name) @name =
name end end attr_accessor
The Basic Some groundwork we need to lay
block
A block is a just chunk of code that can
be called 3.times do puts “hello” end block
A block is just a special form of a proc
def show_me_the_block(&block) block end block vs proc
$ b = show_me_the_block do puts “hello” end => #<Proc:0x00000000d8d600:4>
$ b.call => Hello $ b.class => Proc block vs proc
my_proc = proc { puts “hello” } my_proc.call => hello
3.times &my_proc => hello hello hello block vs proc
A block is a closure because it can access its
environment name = “xinuc” 3.times do puts “hello #{name}” end block & closure
Ruby method lookup
Inside a ruby object klass iv_tbl flags klass iv_tbl flags
m_tbl super object class
Class structure MyClass Object Class super klass klass klass
Class structure Object BasicObject super MyClassA super MyClassB super
Class structure Object BasicObject super MyClassA super MyClassB super MyModule
mixin
eigenclass
o = Object.new o.hello => NoMethodError: undefined method `hello' def
o.hello puts “hello” end o.hello => hello eigen_class
o = Object.new eigen = o.singleton_class #1.9 eigen = class
<< o; self; end eigen_class
Class structure Object BasicObject super MyClassA super eigen_class <virtual> super
MyModule object klass mixin
The Techniques
Define method
# nested def def learn_to_shout puts “learning....” def shout puts
“Wazzzaaaap!!” end end Define method
$ shout => undefined local variable or method `shout' $
learn_to_shout => learning.... $ shout => Wazzzaaaap!! Define method
def learn_to_shout puts “learning....” def shout puts “Wazzzaaaap!!” end end
Define method
def who_are_you puts “I'm batman” def who_are_you puts “I'm superman”
def who_are_you puts “I'm ironman” end end end Define method
def who_are_you puts “I'm batman” def who_are_you puts “I'm superman”
def who_are_you puts “I'm ironman” end end end Hypocrite method
def who_are_you puts “I'm batman” def who_are_you puts “I'm superman”
def who_are_you puts “I'm ironman” end end end Yo dawg method
define_method
define_method method takes a method name and a block, then
creates a method with block as the method body define_method :name do |args| # method body end define_method method
def attr_accessor(*attrs) attrs.each do |attr| define_method attr do instance_variable_get “@#{attr}”
end define_method “#{attr}=” do |val| instance_variable_set “@#{attr}”, val end end end attr_accessor
method_missing
class Person def method_missing(name, *args, &block) puts “method #{name}” end
end p = Person.new p.omg_lol => method omg_lol method_missing
require 'builder' xml = Builder::XmlMarkup.new xml.coder do xml.name 'xinuc' xml.language
'Ruby' end method_missing
Class structure Object BasicObject super MyClass super eigen_class <virtual> super
MyModule my_object klass mixin
Lazy method definition
class Person def method_missing(name, *args, &block) self.class.class_eval do define_method(name) do
puts ”method #{defined} defined” end end self.send name, *args end end Lazy method definition
p = Person.new p.respond_to? :hello => false p.hello => method
hello defined p.respond_to? :hello => true Lazy method definition
class User < ActiveRecord::Base end User.find_by_username “xinuc” Lazy method definition
class_eval
class Person end Person.class_eval do def hello puts “hello” end
end p = Person.new p.hello class_eval
instance_eval
class Person end p = Person.new p.instance_eval do def hello
puts “hello” end end instance_eval
class Person end p = Person.new p.singleton_class.class_eval do def hello
puts “hello” end end p.hello instance_eval
instance_eval change the “self” inside a block s = “Hello”
s.instance_eval do puts self.upcase end instance_eval
# sunspot class User < ActiveRecord::Base # method text &
integer # not defined here searchable do # but we can call method text & integer here text :name integer :age end end instance_eval
Here comes the devil
Class.new Create classes dynamically
1000.times do Class.new do end end Class.new
“The evil” eval
eval <<-EOF def do_evil puts “do evil things” end EOF
do_evil eval
Warning!
Metaprogramming is a chainsaw warning
You don't slice your bread with a chainsaw! warning
Unless you're a bear with chainsaw hands warning
Thank you