LoginSignup
4
4

More than 5 years have passed since last update.

ER 6 Know How Ruby Build Inheritance Hierarachies

Last updated at Posted at 2016-02-13

memo

  • To find a method, Ruby only has to search up the class hierarchy. If it doesn't find the methods it's looking for it starts the search again, trying to find the method_missing method.
  • Including medules siletnly creates singleton classes that are inserted into the hierarchy above the including class.
  • Singleton methods (class methods and per-object methods) are stored in singleton classes that are also inserted into the hierarchy.

Effective Ruby

object

An object is a container of variables. These variables are referred to as instance variables and represent the state of an object. Each object has a special, internal variable that connects it to one and only one class.

class

A class is a container of methods and constatns. Classes are themselves objects. So each class is also a contaner of variables called class variables.

superclass

If class B inherits from class A, then A is the superclass of B. Classes have special, internal variables to keep track of their superclasses.

module

A module is identical to a class in all respects but one. So like classes, modules are objects and are instances of a particular class. While classes are instances of the Class class, modules are instances of the Module class.

Module have many uses in Ruby but for now we're only concerned with how they contribute to the inheritance hieratchy. Althrough Ruby doesn't directrly support multiple inheritance, modules can be mixed into a class with the include method. which has a similar effect.

signleton calss

A singleton class is a confusing term for an anonymous and invisible class in the inheritance hierachy.

They are sometimes referred to as eigenclass or metaclass. Even the source code for the Ruby interperter uses these terms interchangeably.

Singleton classes play important role in Ruby, such as providing a place to store class methods and included from modules. Unlike other classes, they're created dynamically on an as-needed basis by Ruby itself.

receiver

A receiver is the object on which a method is invoked.

Experiment

Create Person class and Customer class which inherits Person. Interesting thing here is singleton class is created automatically.

ancestors shows inherit order. Righ side is super class of left side. http://ruby-doc.org/core-2.3.0/Module.html

included_modules shows what modules are included for this class. Based on ancestors and included_modules, inherit relationship is as follows.

BasicObject
<- Kernel (module)
<- PP::ObjectMixin(module)
<- Object
<- Person
<- Customer

oh. Another interesting thing, we can redefine class in runtime.

If multiple modules are included, these inherit relationship is LIFO. Module's class is Object.

[3] pry(main)> class Person
[3] pry(main)*   def hi
[3] pry(main)*     puts 'hi'
[3] pry(main)*   end
[3] pry(main)* end

[4] pry(main)> class Customer < Person
[4] pry(main)* end


[11] pry(main)> Customer.superclass
=> Person

[12] pry(main)> Customer.singleton_class
=> #<Class:Customer>

[13] pry(main)> Customer.ancestors
=> [Customer, Person, Object, PP::ObjectMixin, Kernel, BasicObject]

[14] pry(main)> Customer.included_modules
=> [PP::ObjectMixin, Kernel]

[16] pry(main)> module PersonMixin
[16] pry(main)*   def name
[16] pry(main)*     puts 'foo'
[16] pry(main)*   end
[16] pry(main)* end

[18] pry(main)> Person.superclass
=> Object

[19] pry(main)> Customer.ancestors
=> [Customer, Person, PersonMixin, Object, PP::ObjectMixin, Kernel, BasicObject]

[20] pry(main)> module PersonMixin2
[20] pry(main)*   def name
[20] pry(main)*     puts 'bar'
[20] pry(main)*   end
[20] pry(main)* end
=> :name

[21] pry(main)> class Person
[21] pry(main)*   include PersonMixin
[21] pry(main)*   include PersonMixin2
[21] pry(main)* end
=> Person

[22] pry(main)> Customer.ancestors
=> [Customer,
 Person,
 PersonMixin2,
 PersonMixin,
 Object,
 PP::ObjectMixin,
 Kernel,
 BasicObject]

[28] pry(main)> Customer.superclass
=> Person

[29] pry(main)> Customer.superclass.superclass
=> Object

[30] pry(main)> Customer.superclass.superclass.superclass
=> BasicObject

[31] pry(main)> Customer.included_modules
=> [PersonMixin2, PersonMixin, PP::ObjectMixin, Kernel]

[37] pry(main)> customer = Customer.new
=> #<Customer:0x007f9de428f008>
[38] pry(main)> def customer.name
[38] pry(main)*   "baz"
[38] pry(main)* end

[42] pry(main)> customer.singleton_methods
=> [:name]

[43] pry(main)> customer.name
=> "baz"
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4