Ruby object model at the Ruby drink-up of Sophia, January 2013
1. An introduction to Ruby's object
model
Riviera.rb – 08/01/2013
Nicolas Bondoux
2. Overview
● Introduction to module and classes
● Singleton class; case of meta-classes
● Tools for meta-programming
● Using modules for extending objects: mixins
3. A simple class
class LinkedElement
#constructor
● A class definition
def initialize(content,link) contains
@content = content
@link = link
end
– Instance methods
# setter – Constants
def content=(content)
@content = content
end
– Class variables
#getter
● Instance variables are
def content
return @content
prefixed by @; they
end are manipulated
# automatic generation setter/getter: through instance
attr_accessor :link
end
methods
5. Objects' equality
● Objects comparison:
– == → true if the content of two objects
– .eql? → true if == and class of the two objects;
● Used alongside with .hash for hash maps
– .equal? : true if the same instance on both sides
● == and .eql? Must be provided by class implementation
6. Classes inheritance
class Toto irb(main):027:0* Toto.new.myNameIs
def myNameIs => "My Name Is Toto."
return "My Name Is #{name}." irb(main):028:0> Titi.new.myNameIs
end => "My Name Is Titi."
def name
"Toto" irb(main):030:0* t = Titi.new
end => #<Titi:0x00000001d376c8>
end irb(main):035:0> t.class
=> Titi
class Titi < Toto irb(main):036:0>
def name t.class.superclass
"Titi" => Toto
end irb(main):037:0> t.is_a? Titi
end => true
irb(main):038:0> t.is_a? Toto
=> true
irb(main):039:0> Toto === t
=> true
irb(main):040:0> Toto.superclass
=> Object
7. Self
● “self” keyword represents the instance in which the code is
executed
– inside a method definition , the instance on which
method is defined
– Inside class/module definition: the class/module being
defined
class TestSelf
puts self
def f
return self
end
end
# display TestSelf
t = TestSelf.new
t.f.equal? t
=> true
8. Class methods and variables
class TestClassMethod
#class variable
@@a=0
#class method
def self.counter
@@a=0
end
#instance method
def putsSelf
puts self
@@a+=1
end
end
● Class are objects: class methods are their instance methods!
● Class variables are prefixed with @@
● Ruby magic: class variables from parent classes are
accessible to child classes
● Class variables are accessible anywhere in class definition
10. Adding methods to a class
● Class definition can be extended anytime
● Let's add a size method to our linked list:
class LinkedElement
def size
@link.size + 1
end
class LinkedElementEnd
def size
0
end
end
end
irb(main):081:0> a.size
=> 1
irb(main):082:0> b.size
=> 2
11. Structs
● Struct.new allow to dynamically create Classes, with getter
and setters
irb(main):008:0> MyClass = Struct.new(:a,:b, :c)
=> MyClass
irb(main):009:0> m = MyClass.new(1,10)
=> m = MyClass.new(1,10)
irb(main):011:0> m.a=2
=> 2
irb(main):013:0> m.to_a
=> [2, 10, nil]
● Instance of struct have, among others .eql?, .equal?, .hash
methods defined !
● Very useful to quickly define records, keys …
● Structs can then be inherited from/extended like any classes
12. Modules
● Module is a parent type of Class;
– A module is an instance of Module
● Modules are like classes, except that
– They cannot be instantiated
– No inheritance: they cannot have parent or child
● Still, they are objects:
– They have instance variables, (class) methods
● And they also have
– class variables
– and instance methods → used for the mixins
● Modules are useful for namespaces
14. A very simplified diagram
Object
MyParentClass Module MyModule
Instance MyClass Class
.class
.superclass
15. Extending instances:
● We have already seen that class methods of a class A are
instance methods specific to the object A
– It is possible to add methods to instances!
a="5"
def a.mult(x)
"#{self.to_i*x}"
znd
irb(main):096:0* a.mult(10)
=> "50"
● Where is stored “mult” Method ? In the Singleton class !
irb(main):103:0> a.singleton_class
=> #<Class:#<String:0x000000018ec7a8>>
irb(main):104:0> a.singleton_class.ancestors
=> [String, Comparable, Object, Kernel, BasicObject]
irb(main):105:0> a.singleton_class.superclass
=> String
16. What are singleton classes ?
● One instance has its own singleton
● Those are anonymous and invisible classes, inserted at the
bottom of the class hierarchy
● They are used to hold methods that are specific to an instance
Object
class String
a (a)
singleton_class
17. Singleton classes of classes: meta-
classes
● Meta-classes: the singleton classes of methods
– This is where class methods are stored!
● Meta-classes magic:
– when looking for a class methods ruby search in the
meta-classes of all the inheritance chain!
– This is because meta-classes inheritance scheme is
parallel to class inheritance scheme
18. Meta-classes: a diagram
Object Class
MyParentClass (MyParentClass)
MyClass (MyClass)
Instance (Instance)
.singleton_class
.superclass
19. Extending the singleton classes
class Toto
#instance method of Toto
# Singleton class can also be
def f
accessed explicitly
end
class << Toto
def h
#class method of Toto
return self
def self.g
end
end
end
end
#class method of Toto
class Toto
def Toto.g
class << self
end
def i1
end
# > def x.g .... > add an instance method to
the singleton class of x !
def i2
end
end
end
# i1 and i2 are class methods of
Toto !!!
20. instance_eval/instance_exec
● instance_eval allow to execute code in the context of an
instance;
– Ruby magic: self represents the instance, but methods
are added to the singleton class!
class TestInstanceEval
def initialize
@a=5
end
end
b=5
irb(main):189:0> t.instance_eval "@a"
=> 5
irb(main):190:0* t.instance_eval "def f; puts @a+#{b};end"
=> nil
irb(main):191:0> t.f
10
21. Mixins
● Mixins are a way to add properties to an object
● They are modules referenced by classes
● Instance methods of the module becomes available to
instances of the class
● Include: the module becomes an included module of the Class
– the instance methods of an module become instance
methods of the Class → used to extend classes
● Extend: the module becomes an included module of the
singleton of the class → allow to extends objects, add class
methods to classes ...