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
140
1
Share
This Talk is so Meta
Introduction to metaprogramming in ruby
Nugroho Herucahyono
September 26, 2013
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
160
Rails on Wiradipa - Jakarta.rb Februari 2012 - Hafiz Badrie Lubiz
xinuc
1
170
Why Ruby? - View from business aspect - Jakarta.rb Februari 2012 - Fajrin Rasyid
xinuc
1
360
Other Decks in Programming
See All in Programming
AI 時代のソフトウェア設計の学び方
masuda220
PRO
29
12k
開発体験を左右するライブラリの API 設計 - GraphQL スキーマ構築ライブラリから考える #tskaigi
izumin5210
2
1.6k
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
540
Why Laravel apps break—Mastering the fundamentals to keep them maintainable
kentaroutakeda
1
340
決定論的オーケストレーションの設計と実装 / Design and Implementation of Deterministic Orchestration
nrslib
3
970
Oxcを導入して開発体験が向上した話
yug1224
4
280
運用エージェントは "作る" から "育てる" へ - 記憶と自己進化の3層設計パターン / self-evolving-agents-three-layer-agent-design
gawa
12
3.4k
軽量Java基盤の設計 DIコンテナに頼らない、長期保守と1秒起動の実現 JJUG CCC 2026 Spring
macha64
0
440
今さら聞けないCancellationToken
htkym
0
220
技術記事、AIに書かせるか、自分で書くか? 〜それでも私が自分の手で書く理由〜 / #QiitaConference
jnchito
2
1.3k
AIとRubyの静的型付け
ukin0k0
0
530
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
240
Featured
See All Featured
Chasing Engaging Ingredients in Design
codingconduct
0
210
Docker and Python
trallard
47
3.9k
Being A Developer After 40
akosma
91
590k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
1.9k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
320
Embracing the Ebb and Flow
colly
88
5.1k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
350
It's Worth the Effort
3n
188
29k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.2k
Amusing Abliteration
ianozsvald
1
200
How GitHub (no longer) Works
holman
316
150k
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