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
C
, no se encuentra
ya que en C
no se han declarado métodos de clase
C
: esta clase es la clase Class
.
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 endPuesto 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:
Fixnum
: no se encuentra
Fixnum
: es Class
.
No se encuentra
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
.
Class
son especiales: tienen superclases.
Class
son también especiales: tienen superclases.
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'
Fixnum.parse
en:
n = Fixnum.parse("1")tendríamos:
Fixnum
: no se encuentra
Fixnum
esta es la eigenclass de Integer
y allí encuentra el método parse
Numeric
y Object.
Es decir, sigue buscando por métodos singleton
Class
,
Module
,
Object y Kernel
Casiano Rodriguez León 2015-01-07