SlideShare a Scribd company logo
Object Model and
Metaprogramming in
Ruby
Monday, November 1, 2010
Santiago Pastorino
@spastorino
Monday, November 1, 2010
Monday, November 1, 2010
Monday, November 1, 2010
Monday, November 1, 2010
Monday, November 1, 2010
Monday, November 1, 2010
Monday, November 1, 2010
Monday, November 1, 2010
Ruby
Rails
Monday, November 1, 2010
Java get/set version 1
public class User {
private String name;
public String getName() {
   return name;
   }
   public void setName(String name) {
   this.name = name;
}
}
Monday, November 1, 2010
.NET get/set version 1
class User
{
private string name;
public string Name
{
    get { return name; }
    set { name = value; }
}
}
Monday, November 1, 2010
Ruby get/set version 1
class User
def name
@name
end
def name=(value)
@name = value
end
end
Monday, November 1, 2010
Java get/set version 2
?public property String name;
Monday, November 1, 2010
.NET get/set version 2
class User
{
public string Name { get; set; }
}
Monday, November 1, 2010
Ruby get/set version 2
The right way
class User
attr_accessor :name
end
Monday, November 1, 2010
Metaprogramming
Monday, November 1, 2010
Metaprogramming
“Metaprogramming is writing code that
writes code.”
Monday, November 1, 2010
Metaprogramming
“Metaprogramming is writing code that
writes code.”
Monday, November 1, 2010
Metaprogramming
“Metaprogramming is writing code that
writes code.”
“Metaprogramming is writing code that
manipulates language constructs at runtime.”
Monday, November 1, 2010
Metaprogramming
Monday, November 1, 2010
Metaprogramming
• Classes are always open
• Everything is an Object even classes and
modules
• All methods calls have a receiver
Monday, November 1, 2010
Classes are Open
class Hash
def except!(*keys)
keys.each { |key| delete(key) }
self
end
end
hsh = {:a => 1, :b => 2}
hsh.except!(:a) # => {:b => 2}
Monday, November 1, 2010
Everything is an Object
class User
puts self # => User
puts self.class # => Class
end
User.methods.grep /get/
=> [:const_get,
:class_variable_get,
:instance_variable_get]
Monday, November 1, 2010
All method calls have a
receiver
class User
attr_accessor :name
end
Monday, November 1, 2010
Metaprogramming
•class_eval
• define_method
• method_missing
Monday, November 1, 2010
attr_reader (class_eval)
class User
def initialize(name)
@name = name
end
attr_reader :name
end
u = User.new(‘Santiago’)
u.name # => ‘Santiago’
Monday, November 1, 2010
attr_reader (class_eval)
class Module
def attr_reader(sym)
class_eval “def #{sym}; @#{sym}; end”
end
end
class User
attr_reader :name # def name; @name; end
end
Monday, November 1, 2010
attr_reader (class_eval)
class Module
private
def attr_reader(sym)
class_eval <<-READER, __FILE__, __LINE__ + 1
def #{sym}
@#{sym}
end
READER
end
end
Monday, November 1, 2010
attr_writer (class_eval)
class Module
private
def attr_writer(sym)
class_eval <<-WRITER, __FILE__, __LINE__ + 1
def #{sym}=(value)
@#{sym} = value
end
WRITER
end
end
Monday, November 1, 2010
attr_accessor
class Module
private
def attr_accessor(*syms)
attr_reader(syms)
attr_writer(syms)
end
end
Monday, November 1, 2010
Metaprogramming
• class_eval
•define_method
• method_missing
Monday, November 1, 2010
define_method
class User
attr_accessor_with_default :age, 22
end
user = User.new
user.age # => 22
user.age = 26
user.age # => 26
Monday, November 1, 2010
define_method
class Module
def attr_accessor_with_default(sym, default)
class_eval <<-READER, __FILE__, __LINE__ + 1
def #{sym}
#{default}
end
# + something else
READER
end
end
Monday, November 1, 2010
define_method
class User
attr_accessor_with_default :age, 22
end
user = User.new
user.age # => 22
Monday, November 1, 2010
define_method
class USer
attr_accessor_with_default :complex_obj,
Struct.new(:x, :y)
end
user = User.new
user.complex_obj # => nil
Monday, November 1, 2010
define_method
22.to_s # => “22”
Struct.new(:x, :y).to_s # => "#<Class:0x00000100966210>"
Monday, November 1, 2010
define_method
class Module
def attr_accessor_with_default(sym, default)
class_eval <<-READER, __FILE__, __LINE__ + 1
def #{sym}
default
end
# + something else
READER
end
end
Monday, November 1, 2010
define_method
class User
attr_accessor_with_default :complex_obj,
Struct.new(:x, :y)
end
user = User.new
user.complex_obj
NameError: undefined local variable or method
`default' for #<User:0x00000100978050>
Monday, November 1, 2010
define_method
class Module
def attr_accessor_with_default(sym, default)
define_method(sym, Proc.new { default })
end
end
Monday, November 1, 2010
define_method
class Module
def attr_accessor_with_default(sym, default)
define_method(sym, Proc.new { default })
class_eval(<<-EVAL, __FILE__, __LINE__ + 1)
def #{sym}=(value)
class << self; attr_accessor :#{sym} end
@#{sym} = value
end
EVAL
end
end
Monday, November 1, 2010
define_method
class Person
attr_accessor_with_default :complex_obj,
Struct.new(:x, :y)
end
person = Person.new
person.complex_obj # => #<Class:0x00000101045c70>
person.complex_obj = Struct.new(:a, :b)
person.complex_obj # => #<Class:0x000001009be9d8>
Monday, November 1, 2010
Metaprogramming
• class_eval
• define_method
•method_missing
Monday, November 1, 2010
Method Lookup
BasicObject
Object
XMLx
KernelKernel
Monday, November 1, 2010
method_missing
(An internal DSL)
XML.generate(STDOUT) do
html do
head do
title { ‘pagetitle’ }
comment ‘This is a test’
end
body do
h1 style: ‘font-family: sans-serif‘ do
‘pagetitle’
end
ul id: ‘info’ do
li { Time.now }
li { RUBY_VERSION }
end
end
end
Monday, November 1, 2010
method_missing
(An internal DSL)
<html>
<head>
<title>pagetitle</title>
<!-- This is a test -->
</head>
<body>
<h1 style=”font-family: sans-serif”>
pagetitle
</h1>
<ul id=”info”>
<li>2010-10-30 17:39:45 -0200</li>
<li>1.9.2</li>
</ul>
</body>
</html>
Monday, November 1, 2010
method_missing
(An internal DSL)
class XML
def initialize(out)
@out = out
end
def content(text)
@out << text.to_s
end
def comment(text)
@out << “<!-- #{text} -->”
end
end
Monday, November 1, 2010
method_missing
(An internal DSL)
def method_missing(tagname, attributes={})
@out << “<#{tagname}”
attributes.each { |attr, value|
@out << “#{attr}=’#{value}’”
}
if block_given?
@out << ‘>’
content = yield
if content
@out << content.to_s
end
@out << “</#{tagname}>”
else
@out << ‘/>’
end
end
Monday, November 1, 2010
method_missing
(An internal DSL)
class XML
def self.generate(out, &block)
XML.new(out).instance_eval(&block)
end
end
XML.generate(STDOUT) do
# code
end
Monday, November 1, 2010
method_missing
(An internal DSL)
XML.generate(STDOUT) do
html do
head do
title { ‘pagetitle’ }
comment ‘This is a test’
end
body do
h1 style: ‘font-family: sans-serif‘ do
‘pagetitle’
end
ul id: ‘info’ do
li { Time.now }
li { RUBY_VERSION }
end
end
end
Monday, November 1, 2010
It’s all about the self
Monday, November 1, 2010
Singleton Method
d = “9/5/1982”
def d.to_date
# code here
end
# or
class << d
def to_date
# code here
end
end
Monday, November 1, 2010
Object Model
BasicObject
Object
String
(d)d
KernelKernel
Monday, November 1, 2010
Class Methods?
class String
def self.to_date
# code here
end
# or
class << self
def to_date
# code here
end
end
end
Monday, November 1, 2010
The same
d = “9/5/1982”
def d.to_date
# code here
end
# or
class << d
def to_date
# code here
end
end
Monday, November 1, 2010
Object Model
(BasicObject)BasicObject
Object (Object)
String (String)
Module
Class
Monday, November 1, 2010
Everything about self
class User
p self # => User
class << self
p self # => <Class:User>
end
end
Monday, November 1, 2010
Real life use cases for
fibers?
require 'fiber'
module Eigenclass
  def eigenclass
    class << self; self end
  end
  module_function :eigenclass
  public :eigenclass
end
class Object
  include Eigenclass
end
Monday, November 1, 2010
Real life use cases for
fibers?
class EigenclassesGenerator
  def initialize(obj)
    @eigenclasses = [obj.eigenclass]
    @fiber = Fiber.new do
      loop do
        Fiber.yield @eigenclasses.last
        @eigenclasses[@eigenclasses.length] = @eigenclasses.last.eigenclass
      end
    end
  end
  def [](index)
if index >= @eigenclasses.length
(index - @eigenclasses.length + 2).times { @fiber.resume }
end
    @eigenclasses[index]
  end
end
Monday, November 1, 2010
Rails Magic?
class User < ActiveRecord::Base
belongs_to :bill_address
has_one :role
has_many :orders
validates_presence_of :name, :country
validates_acceptance_of :terms
validates_uniqueness_of :name
end
Monday, November 1, 2010
Questions?
Monday, November 1, 2010
Thank you!
Monday, November 1, 2010

More Related Content

What's hot (20)

PPTX
JDK 8
Maciej Dragan
 
PPTX
Object oriented concepts
Gousalya Ramachandran
 
PDF
The Ring programming language version 1.2 book - Part 53 of 84
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.5.4 book - Part 6 of 185
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.7 book - Part 78 of 196
Mahmoud Samir Fayed
 
PPT
14. Defining Classes
Intro C# Book
 
PDF
The Ring programming language version 1.7 book - Part 35 of 196
Mahmoud Samir Fayed
 
PDF
The Ring programming language version 1.5.1 book - Part 70 of 180
Mahmoud Samir Fayed
 
DOCX
Java cheat sheet
Saifur Rahman
 
PPTX
Java Polymorphism Part 2
AathikaJava
 
PPTX
Lecture 6 inheritance
manish kumar
 
PDF
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
Maulik Borsaniya
 
PDF
functional groovy
Paul King
 
PPTX
Ch8(oop)
Chhom Karath
 
PDF
Python unit 3 m.sc cs
KALAISELVI P
 
PPT
Class 10 Arrays
Stephen Parsons
 
PDF
The Ring programming language version 1.4 book - Part 20 of 30
Mahmoud Samir Fayed
 
PPTX
Lecture 4_Java Method-constructor_imp_keywords
manish kumar
 
Object oriented concepts
Gousalya Ramachandran
 
The Ring programming language version 1.2 book - Part 53 of 84
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.4 book - Part 6 of 185
Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 78 of 196
Mahmoud Samir Fayed
 
14. Defining Classes
Intro C# Book
 
The Ring programming language version 1.7 book - Part 35 of 196
Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 70 of 180
Mahmoud Samir Fayed
 
Java cheat sheet
Saifur Rahman
 
Java Polymorphism Part 2
AathikaJava
 
Lecture 6 inheritance
manish kumar
 
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
Maulik Borsaniya
 
functional groovy
Paul King
 
Ch8(oop)
Chhom Karath
 
Python unit 3 m.sc cs
KALAISELVI P
 
Class 10 Arrays
Stephen Parsons
 
The Ring programming language version 1.4 book - Part 20 of 30
Mahmoud Samir Fayed
 
Lecture 4_Java Method-constructor_imp_keywords
manish kumar
 

Similar to Metaprogramming (20)

PDF
Metaprogramming in Ruby
Nicolò Calcavecchia
 
PDF
Metaprogramming in Ruby
ConFoo
 
KEY
Metaprogramming
joshbuddy
 
KEY
Ruby objects
Reuven Lerner
 
PDF
Selfish presentation - ruby internals
Wojciech Widenka
 
KEY
Ruby AST Tools
Brian Landau
 
PDF
Ruby — An introduction
Gonçalo Silva
 
KEY
Metaprogramming Primer (Part 1)
Christopher Haupt
 
KEY
Ruby
Kerry Buckley
 
PPT
Ruby Metaprogramming
Wei Jen Lu
 
PDF
Metaprogramming + Ds Ls
ArrrrCamp
 
PDF
Ruby seen from a C# developer
Codemotion
 
PDF
Ruby seen by a C# developer
Emanuele DelBono
 
PPTX
Introduction to Ruby’s Reflection API
Niranjan Sarade
 
PPTX
Deciphering the Ruby Object Model
Karthik Sirasanagandla
 
PDF
Designing Ruby APIs
Wen-Tien Chang
 
PDF
Metaprogramming code-that-writes-code
orga shih
 
KEY
Intro to Ruby - Twin Cities Code Camp 7
Brian Hogan
 
PDF
Introduction to Ruby Programming Language
Nicolò Calcavecchia
 
PDF
Ruby object model at the Ruby drink-up of Sophia, January 2013
rivierarb
 
Metaprogramming in Ruby
Nicolò Calcavecchia
 
Metaprogramming in Ruby
ConFoo
 
Metaprogramming
joshbuddy
 
Ruby objects
Reuven Lerner
 
Selfish presentation - ruby internals
Wojciech Widenka
 
Ruby AST Tools
Brian Landau
 
Ruby — An introduction
Gonçalo Silva
 
Metaprogramming Primer (Part 1)
Christopher Haupt
 
Ruby Metaprogramming
Wei Jen Lu
 
Metaprogramming + Ds Ls
ArrrrCamp
 
Ruby seen from a C# developer
Codemotion
 
Ruby seen by a C# developer
Emanuele DelBono
 
Introduction to Ruby’s Reflection API
Niranjan Sarade
 
Deciphering the Ruby Object Model
Karthik Sirasanagandla
 
Designing Ruby APIs
Wen-Tien Chang
 
Metaprogramming code-that-writes-code
orga shih
 
Intro to Ruby - Twin Cities Code Camp 7
Brian Hogan
 
Introduction to Ruby Programming Language
Nicolò Calcavecchia
 
Ruby object model at the Ruby drink-up of Sophia, January 2013
rivierarb
 
Ad

Recently uploaded (20)

PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PDF
July Patch Tuesday
Ivanti
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PDF
Biography of Daniel Podor.pdf
Daniel Podor
 
PDF
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PPTX
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
July Patch Tuesday
Ivanti
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Biography of Daniel Podor.pdf
Daniel Podor
 
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
POV_ Why Enterprises Need to Find Value in ZERO.pdf
darshakparmar
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
Ad

Metaprogramming