class << selfes 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 ase crea un nuevo método llamado aen Fooeigenclass '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. frobse define, no en la Stringclase, sino en la clase propia de str, una subclase anónima única de String. También strtiene un frobmétodo, pero las instancias de Stringen 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. FooEl método initialize de Inside , selfno 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.
La respuesta más simple: no se puede crear una instancia de la clase propia.
class F def eigen class << self self end end end F.new.eigen.new #=> TypeError: can't create instance of virtual classfuente
Yehuda Katz hace un buen trabajo al explicar las sutilezas en " Metaprogramación en Ruby: se trata de uno mismo "
fuente