SlideShare a Scribd company logo
Magic in Ruby
David Lin
davll.xc@gmail.com
<beer>
Oct. 18, 2013
</beer>
Suppose You Know
1. Ruby Programming Language
- class, module, method
- block
- mixin (include, extend)
2. Metaprogramming
- class_eval
- define_method
3. Monkey Patching
Outline
1. Smalltalk-style method calling
2. Method swizzling
3. Decorator
4. Refinement
Ruby
is

Smalltalk-style!
Objective-C, too.
丟訊息
給物件
看看物件有什麼反應
obj.hello(“world”)
obj.hello(“world”)

這是 message
obj.hello(“world”)

這是 receiver
obj.hello(“world”)
obj.send(:hello,
“world”)
Yes, it sends a message!
obj 接收了message
內容為 hello(“world”)
現在 obj 就要
暴走
同步率400%
obj 找一個對應的
method body
根據 message name :hello
然後...
引爆 invoke
呼叫這個 method body
DEFINE
A METHOD
事實上是定義一個 method body
然後連到對應的 message name
def hello(s)
define a method named ‘hello’
define a method for the name ‘hello’
a method body

:hello
method body
&
message name
沒有綁死在一起
而是可以改變的
HACK IT!
Let’s change behaviour
Method
Swizzling
把 method body “抽換”掉
Example.rb
class MyObj
def hello(s)
“Hello #{s}”
end
end

method body
A

:hello
Hack1.rb (part 1)
class MyObj
alias_method :hello_original,
:hello
end
:hello_original
method body
A

:hello
Hack1.rb (part 2)
class MyObj
def hello_with_bracket(s)
“{” + hello_original(s) + ”}”
end
end
method body
B

:hello_with_bracket
send message

:hello_original
Hack1.rb (part 3)
class MyObj
alias_method :hello,
:hello_with_bracket
end
method body
B
method body
A

:hello_with_bracket

:hello
Hack1.rb (final)
:hello
method body
B

:hello_with_bracket

send message

method body
A

:hello_original
可不可以
更簡潔些?
太多沒必要的 message names
Hack2.rb (to expect)
:hello
method body
B

call directly

method body
A

:hello_with_bracket

send message

:hello_original
Hack2.rb (to expect)
:hello
method body
B

call directly

method body
A
Hack2.rb (yes, that’s all)
class MyObj
m = instance_method(:hello)
define_method(:hello) do |s|
“{” + m.bind(self).call(s) + “}”
end
end
Hack2.rb
class MyObj
m = instance_method(:hello)
define_method(:hello) do |s|
“{” + m.bind(self).call(s) + “}”
end
end
m (a local var)
method body
A

:hello
Hack2.rb
class MyObj
m = instance_method(:hello)
define_method(:hello) do |s|
“{” + m.bind(self).call(s) + “}”
end
end
method body
B
method body
A

:hello
Hack2.rb (Ah, ha!)
class MyObj
m = instance_method(:hello)
define_method(:hello) do |s|
“{” + m.bind(self).call(s) + “}”
end
end
method body
B
call directly

method body
A

:hello
Decorator
Method Wrapping
(it’s more complicant than Python, though)
Example (Unsafe!)
def send_money(from, to, amount)
from.balance -= amount
to.balance += amount
from.save!
to.save!
end
Example (Safer)
def send_money(from, to, amount)
ActiveRecord::Base.transcation do
from.balance -= amount
to.balance += amount
from.save!
to.save!
end
end
Example in Ruby
def send_money(from, to, amount)
ActiveRecord::Base.transcation do
# do operations
end
end
Example in Python
def send_money(from, to, amount):
try:
db.start_transcation()
# do operations
db.commit_transcation()
except:
db.rollback_transcation()
raise
Decorating in Python
Form 1:
@transcational
def send_money(from, to, amount):
# do operations
Form 2:
def send_money(from, to, amount):
# do operations
send_money = transcational(send_money)
Decorator in Python
def transcational(func):
def func2(*args):
try:
db.start_transcation()
func(*args) # call decoratee
db.commit_transcation()
except:
db.rollback_transcation()
raise
return func2
Decorating in Ruby
class Bank
extend Transcational # include decorator
def send_money(from, to, amount)
# do operations
end
transcational :send_money # decorate!
end
Decorator in Ruby
module Transcational
def transcational(mthd_name)
mthd = instance_method(mthd_name)
define_method(mthd_name) do |*args, &blk|
ActiveRecord::Base.transcation {
# call decoratee
mthd.bind(self).call(*args, &blk)
}
end
end
end
這只是
Method
Swizzling
since Ruby has methods but functions
Refinement
For Ruby 2.0+
當你要...
Monkey Patching
Modify existing classes of other libs
Instead of monkey patching
class KlassOrModule
# define instance methods...
end
module MyLibrary
# using modified KlassOrModule...
end
住手!
You’re gonna RUIN EVERYTHING!
Use refinement
module MyLibrary
refine KlassOrModule do
# define instance methods...
end
# using modified KlassOrModule...
end
Example
module MyLibrary
refine String do # modify String
def hello
“Hello #{self}”
end
end
end
Example (cont.)
# Outside MyLibrary

puts “Kitty”.hello
# => NoMethodError: hello
Example (cont.)
# Outside MyLibrary
using MyLibrary
puts “Kitty”.hello
# => Hello Kitty
Inside Refinement
Actually, refinement creates an annoymous
module to mixin a class.
module MyLib
refine String do
puts self.is_a?(Module) # => true
puts self
# => #<refinement:String@MyLibrary>
end
end
Inside Refinement

module MyLib
refine String do

module
<refinement:String@MyLibrary>
end
end
It is ...

Automatic Mixining
自動化MIXIN
When using MyLibrary ...
every new instance of String is extended!
using MyLibrary
puts “x”.hello # “x” is extended
puts String.new(“x”).hello
using is lexical in scope
just like Java’s import
using is lexical
1. Refinements are activated only at top-level
- Not inside class, module, and method scope
2. Scope of the effect is the whole source code
using is lexical
Please DO NOT…
class Foo
using MyLib
end

module Moo
using MyLib
end

def bar
using MyLib
end
using is lexical
# refinement of MyLib is deactived
# “World”.hello # => NoMethodError
using MyLib # activate!
# refinement of MyLib is activated
def hello_world
“World”.hello
end
# END OF FILE

Scope of
MyLib
Refinement
Refinement in Ruby
1. Actually, it is based on Mixining
2. Avoid global scope corruption
3. Prefer lexical scope to runtime scope
=> easy to use, just like import in Java
Better Refinement
than
Monkey Patching
please, get rid of monkey patching.
魔法のRuby
まほうのRuby
本簡報
用高橋流製作
在此向たかはしさん致敬
<FIN>

More Related Content

PDF
Rapid Development with Ruby/JRuby and Rails
PDF
Introduction to Ruby Programming Language
PDF
Objective-C Blocks and Grand Central Dispatch
PDF
Java Strings Tutorial | String Manipulation in Java | Java Tutorial For Begin...
KEY
Parte II Objective C
PPTX
Lecture04 polymorphism
PDF
Java - Strings Concepts
PDF
Javascript: 8 Reasons Every PHP Developer Should Love It
Rapid Development with Ruby/JRuby and Rails
Introduction to Ruby Programming Language
Objective-C Blocks and Grand Central Dispatch
Java Strings Tutorial | String Manipulation in Java | Java Tutorial For Begin...
Parte II Objective C
Lecture04 polymorphism
Java - Strings Concepts
Javascript: 8 Reasons Every PHP Developer Should Love It

What's hot (15)

PDF
2008 07-24 kwpm-threads_and_synchronization
PDF
Shiksharth com java_topics
PPT
Lecture21
PPTX
TURAMBAR: An Approach to Deal with Uncertainty in Semantic Environments
PDF
P6 OO vs Moose (&Moo)
PDF
Javascript foundations: Introducing OO
PPT
C++ programming with jni
PPTX
String java
KEY
jRuby: The best of both worlds
PDF
Anton Kasyanov, Introduction to Python, Lecture5
PDF
Coffee Script
PPT
Lec 42.43 - virtual.functions
PDF
CoffeeScript
KEY
EventMachine for RubyFuZa 2012
PDF
Writing Groovy DSLs
2008 07-24 kwpm-threads_and_synchronization
Shiksharth com java_topics
Lecture21
TURAMBAR: An Approach to Deal with Uncertainty in Semantic Environments
P6 OO vs Moose (&Moo)
Javascript foundations: Introducing OO
C++ programming with jni
String java
jRuby: The best of both worlds
Anton Kasyanov, Introduction to Python, Lecture5
Coffee Script
Lec 42.43 - virtual.functions
CoffeeScript
EventMachine for RubyFuZa 2012
Writing Groovy DSLs
Ad

Viewers also liked (7)

PDF
ZODB Tips and Tricks
KEY
Ruby objects
PDF
Designing Ruby APIs
KEY
MongoDB - Ruby document store that doesn't rhyme with ouch
PPTX
The Black Magic of Ruby Metaprogramming
PDF
HTML Lecture Part 1 of 2
PPTX
Ruby object model
ZODB Tips and Tricks
Ruby objects
Designing Ruby APIs
MongoDB - Ruby document store that doesn't rhyme with ouch
The Black Magic of Ruby Metaprogramming
HTML Lecture Part 1 of 2
Ruby object model
Ad

Similar to Magic in ruby (17)

PDF
Ruby 2.0
PDF
Ruby 程式語言綜覽簡介
PDF
Metaprogramming in Ruby
PDF
Metaprogramming
PDF
メタプログラミングRuby輪読会 1-4章(復習), 5.1~5.3章
PDF
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
PDF
Ruby Programming Language
PPTX
Metaprogramming ruby
PPTX
Ruby :: Training 1
PPTX
Code for Startup MVP (Ruby on Rails) Session 2
KEY
Ruby 2.0: to infinity... and beyond!
PDF
Ruby 入門 第一次就上手
KEY
Refactor like a boss
KEY
An introduction to Ruby
PPT
Ruby Hell Yeah
KEY
Rails by example
PDF
CS169 UC Berkeley Armando Fox Ruby basics
Ruby 2.0
Ruby 程式語言綜覽簡介
Metaprogramming in Ruby
Metaprogramming
メタプログラミングRuby輪読会 1-4章(復習), 5.1~5.3章
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
Ruby Programming Language
Metaprogramming ruby
Ruby :: Training 1
Code for Startup MVP (Ruby on Rails) Session 2
Ruby 2.0: to infinity... and beyond!
Ruby 入門 第一次就上手
Refactor like a boss
An introduction to Ruby
Ruby Hell Yeah
Rails by example
CS169 UC Berkeley Armando Fox Ruby basics

Recently uploaded (20)

PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Electronic commerce courselecture one. Pdf
PPT
Teaching material agriculture food technology
PPTX
Programs and apps: productivity, graphics, security and other tools
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Review of recent advances in non-invasive hemoglobin estimation
Diabetes mellitus diagnosis method based random forest with bat algorithm
Reach Out and Touch Someone: Haptics and Empathic Computing
Encapsulation_ Review paper, used for researhc scholars
Network Security Unit 5.pdf for BCA BBA.
Mobile App Security Testing_ A Comprehensive Guide.pdf
NewMind AI Weekly Chronicles - August'25 Week I
Building Integrated photovoltaic BIPV_UPV.pdf
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Electronic commerce courselecture one. Pdf
Teaching material agriculture food technology
Programs and apps: productivity, graphics, security and other tools
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Unlocking AI with Model Context Protocol (MCP)
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
How UI/UX Design Impacts User Retention in Mobile Apps.pdf

Magic in ruby