SlideShare a Scribd company logo
1 of 23
Download to read offline
Metaprogramming in
Ruby
Nicola Calcavecchia - 24/04/2013
calcavecchia@{elet.polimi.it|gmail.com}
Principles of Programming Languages
1
Metaprogramming
• Writing code that manipulates language constructs at runtime
• In Ruby no distinction:
• Same as “regular” programming
• Enables:
• Code that writes code
• DSLs
• Introspection (e.g., reflection)
2
Introspection
• Allows to get information about objects at runtime
• Methods
• Instance variables
• etc.
class MyClass
! def initialize()
! ! @var1, @var2 = 0, 2
! end
! def my_method
! end
end
m = MyClass.new
m.class
=> MyClass
m.methods
=> # lot of methods ...
m.instance_variables
=> [:@var1, :@var2]
m.public_methods
=> # ...
m.private_methods
=> # ...
m.instance_of? MyClass
=> true
m.instance_of? Object
=> false
m.is_a? MyClass
=> true
m.is_a? Object
=> true
3
Open Classes
• Classes can be “opened” for change
• What about the open/closed principle?
class MyClass
! def a; "method a"; end
end
m = MyClass.new
m.methods - Object.new.methods
=> [:a]
class MyClass
! def b; "method b"; end
end
m.methods - Object.new.methods
=> [:a, :b]
class Numeric
! KILOBYTE = 1024
! def kilobytes
! ! self * KILOBYTE
! end
end
puts 2.kilobytes
=> 2048
4
Monkeypatching
• Refers to the general idea of modifying the runtime code
without modifying the original source code
• Problems:
• Redefining existing methods
• Change methods used in other pieces of the code
• Ruby 2.0 introduced “scoped” monkeypatching
5
Objects and classes
• Objects contains instance variables
• Remember: instance variables exists only when assigned
• Objects contains:
• Instance variables
• Reference to its class
• object_id
class MyClass
! def my_method
! ! @v = 1
! end
end
obj = MyClass.new
obj.my_method
obj1
@v = 1
MyClass
my_method()
object
instance variables
class
methods
class
6
Classes are objects too
• class
• superclass
• All objects inherit from BasicObject
Class.superclass # => Module
Module.superclass # => Object
String.superclass # => Object
Object.superclass # => BasicObject
BasicObject.superclass # => nil
7
Classes and superclasses
obj1
obj2
MyClass
Object
Class
Module
class
class
class
superclass superclass
•What’s the class of Object ?
•What’s the superclass of Module ?
•What’s the class of Class ?
class MyClass; end
obj1 = MyClass.new
obj2 = MyClass.new
BasicObject
superclass
nil
superclass
8
Invoking methods
• Calling a method involves two steps:
1. Method lookup
• Identify receiver class
• Escalate ancestor chain until the method is found
2. Method execution
• The actual code is executed
class A; end
class B < A; end
B.ancestors
=> [B, A, Object, Kernel, BasicObject]
The ancestor chain
includes also modules
9
Ancestor chains
module M
! def my_method
! ! 'M#my_method'
! end
end
class C
! include M
end
class D < C; end
D
C
M
Object
Kernel
BasicObject
10
self
• Every line of Ruby is executed within an object
• Called current object: self
• Only one object holds the self at any given time
• Instance variables and methods (without explicit
receiver) are called on self
• In class or module definition the role of self is
taken by the class or module
class MyClass
! self! # => MyClass
end
11
Calling methods
dynamically
• Remember “sending messages to objects” ?
• Method send sends messages to objects
• Can be used to dynamically call methods
class MyClass
! def my_method(my_arg)
! ! my_arg * 2
! end
end
obj = MyClass.new
obj.send(:my_method, 3)! # => 6
12
Defining methods
dynamically
• Use the Module#define_method method
• Provide a block for the method body
class MyClass
! ["steve", "jeff", "larry"].each{|d|
! ! ! define_method d.to_sym do
! ! ! ! puts d
! ! ! end
! ! }
end
obj = MyClass.new
obj.steve! # => "steve"
obj.jeff! # => "jeff"
obj.larry! # => "larry"
13
method_missing
• What happens if no method is found in the ancestor
hierarchy?
• A method called method_missing is called
• A common idiom is to override this method in order
to intercept unknown messages
• Define ghost methods
• Methods that do not actually exists!
14
An example
class Mapper
! def initialize()
! ! @map = {}
! end
! def add(key, value)
! ! @map[key.downcase] = value
! end
! def method_missing(method_name, *args)
! ! key = method_name.to_s.downcase
! ! return @map[key] if @map.key? key
! end
end
m = Mapper.new
m.add("Rome","IT")
m.add("London","UK")
puts m.rome
puts m.london
15
instance_eval
• Allows to evaluate a piece of code within the
scope of an object
• That is: changes the self for a piece of code
class MyClass
! def initialize
! ! @v = 1
! end
end
obj = MyClass.new
obj.instance_eval do
! self!# => #<MyClass:0x83fd33 @v=1>
! @v! ! # => 1
end
v = 2
obj.instance_eval { @v = v}
obj.instance_eval { @v }! # => 2
BREAKS ENCAPSULATION!
Read/write private data
With great power comes
great responsibility!
16
class_eval
• Evaluates a block in the context of an existing class
• Changes the self (i.e., it reopens the class)
def add_method_to_(a_class)
! a_class.class_eval do
! ! def m
! ! ! "Hello!"
! ! end
! end!!
end
add_method_to String
"abc".m ! # => "Hello!"
More flexible than reopening
it with the class keyword
(i.e., parametric)
17
Singleton methods
• In Ruby it is possible to add a method to a single
instance of an object
str1 = "This is a string!"
str2 = "Another str"
def str1.title?
! self.upcase == self
end
str1.title?!# => false
str2.title?
=> NoMethodError: undefined method `title?' for "Another str":String
18
Singleton methods - 2
• Are stored in special classes called eigenclasses
• Invoking Object#class does not show eigenclasses
• Special syntax to enter in their scope
class << str1
! # Eigenclass scope
! def title?
! ! upcase == self
! end
end
#str1
title?
String
Object
str1
superclass
superclass
Eigenclass
Method lookup
revisited
19
Method aliases
• Introduce new names for methods
class MyClass
! def my_method; 'my_method()'; end
! alias :m :my_method
end
obj = MyClass.new
obj.my_method! # => "my_method()"
obj.m ! ! ! # => "my_method()"
class String
! alias :real_length :length
! def length
! ! real_length > 5 ? 'long' : 'short'
! end
end
We can invoke the method
with two names
Redefine but still use the old one
(this is also called around alias)
20
Kernel#eval
• Instead of taking a block, it takes a string containing the
code
• Code is executed and the result of expression is
returned
a = 1
b = 2
c = eval("a + b")
puts c
=> 3
Problems
• Code injection
• Readability
• etc.
21
Hook methods
• Various aspects of classes and method definition can
be caught at runtime
• Similar to events
• For example method_missing
class String
! def self.inherited(subclass)
! ! puts "#{self} was inherited by
#{subclass}"
! end
end
class MyString < String; end
=> "String was inherited by MyString"
module M
! def self.included(other_mod)
! ! "M was mixed into #{other_mod}"
! end
end
class C
! include M
end
=> "M was mixed into C"
22
References
23

More Related Content

What's hot

A Scala Corrections Library
A Scala Corrections LibraryA Scala Corrections Library
A Scala Corrections LibraryPaul Phillips
 
Selfish presentation - ruby internals
Selfish presentation - ruby internalsSelfish presentation - ruby internals
Selfish presentation - ruby internalsWojciech Widenka
 
From android/java to swift (3)
From android/java to swift (3)From android/java to swift (3)
From android/java to swift (3)allanh0526
 
Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To ScalaPeter Maas
 
javascript objects
javascript objectsjavascript objects
javascript objectsVijay Kalyan
 
Advanced Python : Static and Class Methods
Advanced Python : Static and Class Methods Advanced Python : Static and Class Methods
Advanced Python : Static and Class Methods Bhanwar Singh Meena
 
Scala uma poderosa linguagem para a jvm
Scala   uma poderosa linguagem para a jvmScala   uma poderosa linguagem para a jvm
Scala uma poderosa linguagem para a jvmIsaias Barroso
 
LinkedIn TBC JavaScript 100: Intro
LinkedIn TBC JavaScript 100: IntroLinkedIn TBC JavaScript 100: Intro
LinkedIn TBC JavaScript 100: IntroAdam Crabtree
 
JavaScript Beyond jQuery
JavaScript Beyond jQueryJavaScript Beyond jQuery
JavaScript Beyond jQueryBobby Bryant
 
All You Need to Know About Type Script
All You Need to Know About Type ScriptAll You Need to Know About Type Script
All You Need to Know About Type ScriptFolio3 Software
 
Javascript basics
Javascript basicsJavascript basics
Javascript basicsSolv AS
 
The JavaScript Programming Language
The JavaScript Programming LanguageThe JavaScript Programming Language
The JavaScript Programming LanguageRaghavan Mohan
 
10 Things I Hate About Scala
10 Things I Hate About Scala10 Things I Hate About Scala
10 Things I Hate About ScalaMeir Maor
 
High Wizardry in the Land of Scala
High Wizardry in the Land of ScalaHigh Wizardry in the Land of Scala
High Wizardry in the Land of Scaladjspiewak
 
JavaScript Programming
JavaScript ProgrammingJavaScript Programming
JavaScript ProgrammingSehwan Noh
 
Ponies and Unicorns With Scala
Ponies and Unicorns With ScalaPonies and Unicorns With Scala
Ponies and Unicorns With ScalaTomer Gabel
 

What's hot (20)

A Scala Corrections Library
A Scala Corrections LibraryA Scala Corrections Library
A Scala Corrections Library
 
Selfish presentation - ruby internals
Selfish presentation - ruby internalsSelfish presentation - ruby internals
Selfish presentation - ruby internals
 
From android/java to swift (3)
From android/java to swift (3)From android/java to swift (3)
From android/java to swift (3)
 
Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To Scala
 
javascript objects
javascript objectsjavascript objects
javascript objects
 
JavsScript OOP
JavsScript OOPJavsScript OOP
JavsScript OOP
 
Advanced Python : Static and Class Methods
Advanced Python : Static and Class Methods Advanced Python : Static and Class Methods
Advanced Python : Static and Class Methods
 
Scala uma poderosa linguagem para a jvm
Scala   uma poderosa linguagem para a jvmScala   uma poderosa linguagem para a jvm
Scala uma poderosa linguagem para a jvm
 
TypeScript
TypeScriptTypeScript
TypeScript
 
LinkedIn TBC JavaScript 100: Intro
LinkedIn TBC JavaScript 100: IntroLinkedIn TBC JavaScript 100: Intro
LinkedIn TBC JavaScript 100: Intro
 
JavaScript Beyond jQuery
JavaScript Beyond jQueryJavaScript Beyond jQuery
JavaScript Beyond jQuery
 
All You Need to Know About Type Script
All You Need to Know About Type ScriptAll You Need to Know About Type Script
All You Need to Know About Type Script
 
Javascript basics
Javascript basicsJavascript basics
Javascript basics
 
The JavaScript Programming Language
The JavaScript Programming LanguageThe JavaScript Programming Language
The JavaScript Programming Language
 
10 Things I Hate About Scala
10 Things I Hate About Scala10 Things I Hate About Scala
10 Things I Hate About Scala
 
High Wizardry in the Land of Scala
High Wizardry in the Land of ScalaHigh Wizardry in the Land of Scala
High Wizardry in the Land of Scala
 
06. haskell type builder
06. haskell type builder06. haskell type builder
06. haskell type builder
 
JavaScript Programming
JavaScript ProgrammingJavaScript Programming
JavaScript Programming
 
Ponies and Unicorns With Scala
Ponies and Unicorns With ScalaPonies and Unicorns With Scala
Ponies and Unicorns With Scala
 
Clojure 7-Languages
Clojure 7-LanguagesClojure 7-Languages
Clojure 7-Languages
 

Similar to Metaprogramming in Ruby

Metaprogramming Primer (Part 1)
Metaprogramming Primer (Part 1)Metaprogramming Primer (Part 1)
Metaprogramming Primer (Part 1)Christopher Haupt
 
Ruby :: Training 1
Ruby :: Training 1Ruby :: Training 1
Ruby :: Training 1Pavel Tyk
 
Rapid Application Development using Ruby on Rails
Rapid Application Development using Ruby on RailsRapid Application Development using Ruby on Rails
Rapid Application Development using Ruby on RailsSimobo
 
Metaprogramming code-that-writes-code
Metaprogramming code-that-writes-codeMetaprogramming code-that-writes-code
Metaprogramming code-that-writes-codeorga shih
 
Ruby object model at the Ruby drink-up of Sophia, January 2013
Ruby object model at the Ruby drink-up of Sophia, January 2013Ruby object model at the Ruby drink-up of Sophia, January 2013
Ruby object model at the Ruby drink-up of Sophia, January 2013rivierarb
 
Advanced Reflection in Pharo
Advanced Reflection in PharoAdvanced Reflection in Pharo
Advanced Reflection in PharoPharo
 
The Dark Side of Objective-C
The Dark Side of Objective-CThe Dark Side of Objective-C
The Dark Side of Objective-CMartin Kiss
 
Advanced Reflection in Pharo
Advanced Reflection in PharoAdvanced Reflection in Pharo
Advanced Reflection in PharoMarcus Denker
 
Metaprogramming With Ruby
Metaprogramming With RubyMetaprogramming With Ruby
Metaprogramming With RubyFarooq Ali
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
Type Profiler: An Analysis to guess type signatures
Type Profiler: An Analysis to guess type signaturesType Profiler: An Analysis to guess type signatures
Type Profiler: An Analysis to guess type signaturesmametter
 
Core java complete ppt(note)
Core java  complete  ppt(note)Core java  complete  ppt(note)
Core java complete ppt(note)arvind pandey
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the BasicsMichael Koby
 

Similar to Metaprogramming in Ruby (20)

Metaprogramming Primer (Part 1)
Metaprogramming Primer (Part 1)Metaprogramming Primer (Part 1)
Metaprogramming Primer (Part 1)
 
Ruby objects
Ruby objectsRuby objects
Ruby objects
 
Ruby :: Training 1
Ruby :: Training 1Ruby :: Training 1
Ruby :: Training 1
 
Metaprogramming
MetaprogrammingMetaprogramming
Metaprogramming
 
Rapid Application Development using Ruby on Rails
Rapid Application Development using Ruby on RailsRapid Application Development using Ruby on Rails
Rapid Application Development using Ruby on Rails
 
Metaprogramming code-that-writes-code
Metaprogramming code-that-writes-codeMetaprogramming code-that-writes-code
Metaprogramming code-that-writes-code
 
Ruby object model at the Ruby drink-up of Sophia, January 2013
Ruby object model at the Ruby drink-up of Sophia, January 2013Ruby object model at the Ruby drink-up of Sophia, January 2013
Ruby object model at the Ruby drink-up of Sophia, January 2013
 
Advanced Reflection in Pharo
Advanced Reflection in PharoAdvanced Reflection in Pharo
Advanced Reflection in Pharo
 
The Dark Side of Objective-C
The Dark Side of Objective-CThe Dark Side of Objective-C
The Dark Side of Objective-C
 
Advanced Reflection in Pharo
Advanced Reflection in PharoAdvanced Reflection in Pharo
Advanced Reflection in Pharo
 
Metaprogramming With Ruby
Metaprogramming With RubyMetaprogramming With Ruby
Metaprogramming With Ruby
 
Python oop third class
Python oop   third classPython oop   third class
Python oop third class
 
6 Object Oriented Programming
6 Object Oriented Programming6 Object Oriented Programming
6 Object Oriented Programming
 
Python advance
Python advancePython advance
Python advance
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
How to write Ruby extensions with Crystal
How to write Ruby extensions with CrystalHow to write Ruby extensions with Crystal
How to write Ruby extensions with Crystal
 
unit 2 java.pptx
unit 2 java.pptxunit 2 java.pptx
unit 2 java.pptx
 
Type Profiler: An Analysis to guess type signatures
Type Profiler: An Analysis to guess type signaturesType Profiler: An Analysis to guess type signatures
Type Profiler: An Analysis to guess type signatures
 
Core java complete ppt(note)
Core java  complete  ppt(note)Core java  complete  ppt(note)
Core java complete ppt(note)
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the Basics
 

Recently uploaded

New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 

Recently uploaded (20)

New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 

Metaprogramming in Ruby

  • 1. Metaprogramming in Ruby Nicola Calcavecchia - 24/04/2013 calcavecchia@{elet.polimi.it|gmail.com} Principles of Programming Languages 1
  • 2. Metaprogramming • Writing code that manipulates language constructs at runtime • In Ruby no distinction: • Same as “regular” programming • Enables: • Code that writes code • DSLs • Introspection (e.g., reflection) 2
  • 3. Introspection • Allows to get information about objects at runtime • Methods • Instance variables • etc. class MyClass ! def initialize() ! ! @var1, @var2 = 0, 2 ! end ! def my_method ! end end m = MyClass.new m.class => MyClass m.methods => # lot of methods ... m.instance_variables => [:@var1, :@var2] m.public_methods => # ... m.private_methods => # ... m.instance_of? MyClass => true m.instance_of? Object => false m.is_a? MyClass => true m.is_a? Object => true 3
  • 4. Open Classes • Classes can be “opened” for change • What about the open/closed principle? class MyClass ! def a; "method a"; end end m = MyClass.new m.methods - Object.new.methods => [:a] class MyClass ! def b; "method b"; end end m.methods - Object.new.methods => [:a, :b] class Numeric ! KILOBYTE = 1024 ! def kilobytes ! ! self * KILOBYTE ! end end puts 2.kilobytes => 2048 4
  • 5. Monkeypatching • Refers to the general idea of modifying the runtime code without modifying the original source code • Problems: • Redefining existing methods • Change methods used in other pieces of the code • Ruby 2.0 introduced “scoped” monkeypatching 5
  • 6. Objects and classes • Objects contains instance variables • Remember: instance variables exists only when assigned • Objects contains: • Instance variables • Reference to its class • object_id class MyClass ! def my_method ! ! @v = 1 ! end end obj = MyClass.new obj.my_method obj1 @v = 1 MyClass my_method() object instance variables class methods class 6
  • 7. Classes are objects too • class • superclass • All objects inherit from BasicObject Class.superclass # => Module Module.superclass # => Object String.superclass # => Object Object.superclass # => BasicObject BasicObject.superclass # => nil 7
  • 8. Classes and superclasses obj1 obj2 MyClass Object Class Module class class class superclass superclass •What’s the class of Object ? •What’s the superclass of Module ? •What’s the class of Class ? class MyClass; end obj1 = MyClass.new obj2 = MyClass.new BasicObject superclass nil superclass 8
  • 9. Invoking methods • Calling a method involves two steps: 1. Method lookup • Identify receiver class • Escalate ancestor chain until the method is found 2. Method execution • The actual code is executed class A; end class B < A; end B.ancestors => [B, A, Object, Kernel, BasicObject] The ancestor chain includes also modules 9
  • 10. Ancestor chains module M ! def my_method ! ! 'M#my_method' ! end end class C ! include M end class D < C; end D C M Object Kernel BasicObject 10
  • 11. self • Every line of Ruby is executed within an object • Called current object: self • Only one object holds the self at any given time • Instance variables and methods (without explicit receiver) are called on self • In class or module definition the role of self is taken by the class or module class MyClass ! self! # => MyClass end 11
  • 12. Calling methods dynamically • Remember “sending messages to objects” ? • Method send sends messages to objects • Can be used to dynamically call methods class MyClass ! def my_method(my_arg) ! ! my_arg * 2 ! end end obj = MyClass.new obj.send(:my_method, 3)! # => 6 12
  • 13. Defining methods dynamically • Use the Module#define_method method • Provide a block for the method body class MyClass ! ["steve", "jeff", "larry"].each{|d| ! ! ! define_method d.to_sym do ! ! ! ! puts d ! ! ! end ! ! } end obj = MyClass.new obj.steve! # => "steve" obj.jeff! # => "jeff" obj.larry! # => "larry" 13
  • 14. method_missing • What happens if no method is found in the ancestor hierarchy? • A method called method_missing is called • A common idiom is to override this method in order to intercept unknown messages • Define ghost methods • Methods that do not actually exists! 14
  • 15. An example class Mapper ! def initialize() ! ! @map = {} ! end ! def add(key, value) ! ! @map[key.downcase] = value ! end ! def method_missing(method_name, *args) ! ! key = method_name.to_s.downcase ! ! return @map[key] if @map.key? key ! end end m = Mapper.new m.add("Rome","IT") m.add("London","UK") puts m.rome puts m.london 15
  • 16. instance_eval • Allows to evaluate a piece of code within the scope of an object • That is: changes the self for a piece of code class MyClass ! def initialize ! ! @v = 1 ! end end obj = MyClass.new obj.instance_eval do ! self!# => #<MyClass:0x83fd33 @v=1> ! @v! ! # => 1 end v = 2 obj.instance_eval { @v = v} obj.instance_eval { @v }! # => 2 BREAKS ENCAPSULATION! Read/write private data With great power comes great responsibility! 16
  • 17. class_eval • Evaluates a block in the context of an existing class • Changes the self (i.e., it reopens the class) def add_method_to_(a_class) ! a_class.class_eval do ! ! def m ! ! ! "Hello!" ! ! end ! end!! end add_method_to String "abc".m ! # => "Hello!" More flexible than reopening it with the class keyword (i.e., parametric) 17
  • 18. Singleton methods • In Ruby it is possible to add a method to a single instance of an object str1 = "This is a string!" str2 = "Another str" def str1.title? ! self.upcase == self end str1.title?!# => false str2.title? => NoMethodError: undefined method `title?' for "Another str":String 18
  • 19. Singleton methods - 2 • Are stored in special classes called eigenclasses • Invoking Object#class does not show eigenclasses • Special syntax to enter in their scope class << str1 ! # Eigenclass scope ! def title? ! ! upcase == self ! end end #str1 title? String Object str1 superclass superclass Eigenclass Method lookup revisited 19
  • 20. Method aliases • Introduce new names for methods class MyClass ! def my_method; 'my_method()'; end ! alias :m :my_method end obj = MyClass.new obj.my_method! # => "my_method()" obj.m ! ! ! # => "my_method()" class String ! alias :real_length :length ! def length ! ! real_length > 5 ? 'long' : 'short' ! end end We can invoke the method with two names Redefine but still use the old one (this is also called around alias) 20
  • 21. Kernel#eval • Instead of taking a block, it takes a string containing the code • Code is executed and the result of expression is returned a = 1 b = 2 c = eval("a + b") puts c => 3 Problems • Code injection • Readability • etc. 21
  • 22. Hook methods • Various aspects of classes and method definition can be caught at runtime • Similar to events • For example method_missing class String ! def self.inherited(subclass) ! ! puts "#{self} was inherited by #{subclass}" ! end end class MyString < String; end => "String was inherited by MyString" module M ! def self.included(other_mod) ! ! "M was mixed into #{other_mod}" ! end end class C ! include M end => "M was mixed into C" 22