En Ruby, definir una clase anidada es similar a definir una clase en un módulo. En realidad, no fuerza una asociación entre las clases, solo crea un espacio de nombres para las constantes. (Los nombres de clase y módulo son constantes).
La respuesta aceptada no era correcta sobre nada. 1 En el ejemplo a continuación, creo una instancia de la clase encerrada léxicamente sin que exista una instancia de la clase encerradora.
class A; class B; end; end
A::B.new
Las ventajas son las mismas que para los módulos: encapsulación, agrupación de código utilizado en un solo lugar y colocación de código más cerca de donde se utiliza. Un proyecto grande puede tener un módulo externo que ocurre una y otra vez en cada archivo fuente y contiene muchas definiciones de clase. Cuando los diversos marcos y códigos de biblioteca hacen esto, solo contribuyen con un nombre al nivel superior, lo que reduce la posibilidad de conflictos. Prosaico, sin duda, pero es por eso que se usan.
El uso de una clase en lugar de un módulo para definir el espacio de nombres externo puede tener sentido en un programa o script de un archivo, o si ya usa la clase de nivel superior para algo, o si realmente va a agregar código para vincular las clases juntas en verdadera clase interna estilo de . Ruby no tiene clases internas, pero nada le impide crear el mismo comportamiento en el código. Hacer referencia a los objetos externos de los internos aún requerirá puntear desde la instancia del objeto externo, pero anidar las clases sugerirá que esto es lo que podría estar haciendo. Un programa cuidadosamente modularizado siempre puede crear primero las clases que lo encierran, y razonablemente se pueden descomponer con clases anidadas o internas. No puedes llamar new
a un módulo.
Puede usar el patrón general incluso para scripts, donde el espacio de nombres no es muy necesario, solo por diversión y práctica ...
#!/usr/bin/env ruby
class A
class Realwork_A
...
end
class Realwork_B
...
end
def run
...
end
self
end.new.run
Car.new
yCar::Wheel.new
. Definitivamente no necesita inicializar unCar
objeto para inicializar unCar::Wheel
objeto en Ruby, pero laCar
clase debe cargarse y ejecutarse paraCar::Wheel
que se pueda usar.