Búsqueda de Métodos de Clase

El algoritmo de resolución para los métodos de clase es el mismo que para los métodos de instancia, pero con un cambio importante.

Supongamos esta clase C sin métodos:

class C
end

Supongamos la llamada:

c = C.new

  1. Ruby busca en la eigenclass de C, no se encuentra ya que en C no se han declarado métodos de clase
  2. Se busca a continuación en la clase de C: esta clase es la clase Class.

  3. En Class ruby encuentra el método de instancia new y lo invoca

En Ruby cualquier invocación a un método implica un objeto receptor y un nombre de método. Si nuestro objeto es una instancia de la clase Class entonces nuestro objeto es una clase.

Para explicar en que consiste el cambio importante en la búsqueda de métodos de clase mencionado antes, consideremos este otro ejemplo en el que definimos un método de clase Integer.parse:

def Integer.parse(text)
  text.to_i
end
Puesto que Fixnum es una subclase de Integer deberíamos poder invocarlo así:
n = Fixnum.parse("1")
[3] pry(main)> Class.ancestors
=> [Class, Module, Object, PP::ObjectMixin, Kernel, BasicObject]
[4] pry(main)> Fixnum.ancestors
=> [Fixnum,
 Integer,
 Numeric,
 Comparable,
 Object,
 PP::ObjectMixin,
 Kernel,
 BasicObject]
Si aplicamos el method lookup para métodos de instancia 14.13 tendríamos:
  1. Se busca en la eigenclass de Fixnum: no se encuentra
  2. Se busca en la clase de Fixnum: es Class. No se encuentra
  3. Se busca en Module, Object, Kernel y BasicObject infructuosamente

Falla. ¿Donde se encuentra alojado el método parse?. Sabemos que parse es un método singleton del objeto Integer. Por tanto está en la eigenclass/singleton class de Integer.

  1. Los objetos de la clase Class son especiales: tienen superclases.
  2. Las singleton clases o eigenclases de los objetos de la clase Class son también especiales: tienen superclases.
  3. La eigenclass de un objeto ordinario no tiene superclase
  4. Si la clase A hereda de la clase B (esto es A < B) y A' denota la eigenclass de A y B' denota la eigenclass de B, entonces la superclase de A' es B'
  5. Ruby para los métodos singleton busca en la eigenclass del objeto y en todas las superclases de la eigenclass
Si aplicamos el nuevo lookup a la búsqueda de Fixnum.parse en:
n = Fixnum.parse("1")
tendríamos:

  1. Se busca en la eigenclass de Fixnum: no se encuentra
  2. Busca en la superclase de la eigenclass de Fixnum esta es la eigenclass de Integer y allí encuentra el método parse
  3. Si no lo hubiera encontrado hubiera probado con las subsiguientes eigenclasses de Numeric y Object. Es decir, sigue buscando por métodos singleton
  4. Después probaría con Class, Module, Object y Kernel

Casiano Rodriguez León 2015-06-18