SlideShare una empresa de Scribd logo
1 de 23
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

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
 

La actualidad más candente (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 a 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 a 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
 

Último

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 

Último (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 

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