class << self
es más que una forma de declarar métodos de clase (aunque se puede usar de esa manera). Probablemente hayas visto algún uso como:
class Foo
class << self
def a
print "I could also have been defined as def Foo.a."
end
end
end
Esto funciona, y es equivalente a def Foo.a
, pero la forma en que funciona es un poco sutil. El secreto es que self
, en ese contexto, se refiere al objeto Foo
, cuya clase es una subclase única y anónima de Class
. Esta subclase se llama Foo
's eigenclass . Así def a
se crea un nuevo método llamado a
en Foo
eigenclass 's, con acceso por la sintaxis de llamada método normal: Foo.a
.
Ahora veamos un ejemplo diferente:
str = "abc"
other_str = "def"
class << str
def frob
return self + "d"
end
end
print str.frob
print other_str.frob
Este ejemplo es el mismo que el anterior, aunque puede ser difícil saberlo al principio. frob
se define, no en la String
clase, sino en la clase propia de str
, una subclase anónima única de String
. También str
tiene un frob
método, pero las instancias de String
en general no. También podríamos tener métodos anulados de String (muy útiles en ciertos escenarios de prueba complicados).
Ahora estamos equipados para comprender su ejemplo original. Foo
El método initialize de Inside , self
no se refiere a la clase Foo
, sino a alguna instancia particular de Foo
. Su clase propia es una subclase de Foo
, pero no lo es Foo
; no podría ser, o el truco que vimos en el segundo ejemplo no podría funcionar. Entonces, para continuar con tu ejemplo:
f1 = Foo.new(:weasels)
f2 = Foo.new(:monkeys)
f1.weasels = 4
f2.monkeys = 5
print(f1.monkeys)
Espero que esto ayude.