Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

1,207 views

Published on

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

Published in: Technology
  • Be the first to comment

  • Be the first to like this

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

  1. 1. An introduction to Rubys object model Riviera.rb – 08/01/2013 Nicolas Bondoux
  2. 2. Overview● Introduction to module and classes● Singleton class; case of meta-classes● Tools for meta-programming● Using modules for extending objects: mixins
  3. 3. 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
  4. 4. 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
  5. 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. 6. 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
  7. 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. 8. 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
  9. 9. 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>>>
  10. 10. 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
  11. 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. 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
  13. 13. 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
  14. 14. A very simplified diagram Object MyParentClass Module MyModuleInstance MyClass Class .class .superclass
  15. 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. 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. 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. 18. Meta-classes: a diagram Object Class MyParentClass (MyParentClass) MyClass (MyClass)Instance (Instance) .singleton_class .superclass
  19. 19. 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 !!!
  20. 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. 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 ...
  22. 22. 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]
  23. 23. Any questions?

×