• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Ruby object model at the Ruby drink-up of Sophia, January 2013

Ruby object model at the Ruby drink-up of Sophia, January 2013



Presented at the Ruby Drink-up of Sophia Antipolis on the 8th of January 2013 by Nicolas Bondoux (@nicolas_bondoux).

Presented at the Ruby Drink-up of Sophia Antipolis on the 8th of January 2013 by Nicolas Bondoux (@nicolas_bondoux).



Total Views
Views on SlideShare
Embed Views



0 Embeds 0

No embeds



Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

    Ruby object model at the Ruby drink-up of Sophia, January 2013 Ruby object model at the Ruby drink-up of Sophia, January 2013 Presentation Transcript

    • An introduction to Rubys object model Riviera.rb – 08/01/2013 Nicolas Bondoux
    • Overview● Introduction to module and classes● Singleton class; case of meta-classes● Tools for meta-programming● Using modules for extending objects: mixins
    • A simple classclass 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 :linkend   methods
    • Class instancesirb(main):192:0> a = LinkedElement.new("a", nil)=> #<LinkedElement:0x00000001b63b58 @content="a", @link=nil>irb(main):193:0> b = LinkedElement.new("b",a)=> #<LinkedElement:0x00000001b5daf0 @content="b", @link=#<LinkedElement:0x00000001b63b58 @content="a", @link=nil>>irb(main):194:0> b.link()=> #<LinkedElement:0x00000001b63b58 @content="a", @link=nil>irb(main):195:0> b.@linkSyntaxError: (irb):195: syntax error, unexpected tIVAR from /usr/bin/irb:12:in `<main>irb(main):196:0> b.content=> "b"b.instance_variables=> [:@content, :@link]● A class be instantiated using #new (class method)● Instance variables live within the instance, but are not directly accessible → need of getter and setters
    • 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
    • Classes inheritanceclass 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 => Titiclass Titi < Toto irb(main):036:0>   def name t.class.superclass    "Titi" => Toto  end irb(main):037:0> t.is_a? Titiend => true irb(main):038:0> t.is_a? Toto => true irb(main):039:0> Toto === t => true irb(main):040:0> Toto.superclass => Object
    • 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
    • Class methods and variablesclass TestClassMethod  #class variable  @@a=0  #class method  def self.counter    @@a=0  end  #instance method  def putsSelf    puts self    @@a+=1  endend● 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
    • Classes methods: exampleclass LinkedElement  class LinkedElementEnd  end  #class variable  @@end = LinkedElementEnd.new  #example of constant  End = @@end  #class method  def self.end    @@end  endendirb(main):015:0* LinkedElement.end().equal? LinkedElement::End=> trueirb(main):016:0> LinkedElement.class_variables=> [:@@end]irb(main):069:0>  a= LinkedElement.new("a", LinkedElement.end)=> #<LinkedElement:0x00000001931df8 @content="a", @link=#<LinkedElement::LinkedElementEnd:0x0000000152e8c8>>irb(main):070:0> b=LinkedElement.new("b",a)=> #<LinkedElement:0x0000000192a8c8 @content="b", @link=#<LinkedElement:0x00000001931df8 @content="a", @link=#<LinkedElement::LinkedElementEnd:0x0000000152e8c8>>>
    • Adding methods to a class● Class definition can be extended anytime● Lets 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
    • 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
    • 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
    • Modules (2)module M1  #constant:  C=1  def self.f    "f1; self is #{self}"  endendmodule M2  def self.f    "f2; self is #{self}"  endendirb(main):026:0* M1.f=> "f1; self is M1"irb(main):028:0* M2.f=> "f2; self is M2"irb(main):033:0> M1::C=> 1
    • A very simplified diagram Object MyParentClass Module MyModuleInstance MyClass Class .class .superclass
    • 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
    • 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
    • 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
    • Meta-classes: a diagram Object Class MyParentClass (MyParentClass) MyClass (MyClass)Instance (Instance) .singleton_class .superclass
    • Extending the singleton classesclass 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 endend#class method of Toto class Totodef Toto.g   class << selfend     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 !!!
    • 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
    • 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 ...
    • Mixins: examplesmodule AppendModule  def append(x)    return LinkedElement.new(x,self)  endend#add append method to LinkedElement and LinkedElementEndclass LinkedElement  #add append as instance method of LinkedElement  include AppendModule  class LinkedElementEnd    include AppendModule  endendirb(main):268:0> l = LinkedElement::End.append("z").append("y").append("x")=> #<LinkedElement:0x00000001d18138 @content="x", @link=#<LinkedElement:0x00000001d18188 @content="y", @link=#<LinkedElement:0x00000001d181d8 @content="z", @link=#<LinkedElement::LinkedElementEnd:0x00000001f04f78>>>>irb(main):269:0> l.size=> 3irb(main):270:0> LinkedElement.included_modules=> [AppendModule, Kernel]
    • Any questions?