una otra objetos objeto metodos instanciar externas dentro crear constructores como clases clase anidar anidados anidadas anidada ruby macruby

otra - ¿Cómo puede una clase anidada acceder a un método en la clase externa en Ruby?



meter una clase dentro de otra java (6)

¿Se suponía que era un método de clase para la clase A ?

class A def self.a raise "hi" end class B def b A::a end end end A::B.new.b

Si desea mantenerlo como un método de instancia, obviamente tendrá que llamarlo en una instancia, como por ejemplo A.new.a

def class A def a raise "hi" #can''t be reached end class B def b a() #doesn''t find method a. end end end

Quiero invocar a de b y levantar la excepción. ¿Cómo puedo?


Bueno, dependiendo de tus circunstancias, en realidad hay una solución, bastante fácil. Ruby permite la captura de llamadas a métodos que no son capturadas por el objeto. Así que para tu ejemplo podrías hacer:

def class A def a raise "hi" #can''t be reached end class B def initialize() @parent = A.new end def b a() #does find method a. end def method_missing(*args) if @parent.respond_to?(method) @parent.send(*args) else super end end end end

Entonces si haces esto:

A::B.new().b

usted obtiene:

!! #<RuntimeError: hi>

Probablemente es una forma más fácil de hacer algo como un SubController que solo maneja ciertas actividades, pero que puede llamar fácilmente a los métodos básicos del controlador (aunque desearía enviar el controlador principal como un argumento en el inicializador).

Obviamente, esto debe usarse con moderación, y puede llegar a ser confuso si lo usa en todo el lugar, pero puede ser realmente bueno simplificar su código.


Esto es solo para el lulz:

class A def a puts "hello from a" end class B def b Module.nesting[1].new.a() end end end


Normalmente hago algo como esto:

class A def a puts "hi" end def createB B.new self end class B def initialize(parent) @parent=parent end def b @parent.a end end end A.new.createB.b


Ruby no tiene clases anidadas.

La única forma de heredar el comportamiento es, bueno, a través de la herencia.

Si desea que su código funcione, necesita usar un idioma que admita clases anidadas. Si bien esta es una característica increíblemente nítida y potente, desafortunadamente solo conozco dos idiomas que tienen clases anidadas:

No sé de ningún otro.

Java tiene una construcción llamada clases anidadas, pero tienen algunas limitaciones de diseño desafortunadas.

En su ejemplo anterior, no es la clase B que está anidada dentro de A , es la constante B que está anidada dentro de A Piensa sobre esto:

C = A::B

Ahora, la clase está disponible bajo dos nombres: A::B y C Debe ser inmediatamente obvio que C es global y no está anidado dentro de A (Bueno, en realidad, C está anidado dentro de Object , porque tampoco hay realmente constantes globales, pero eso no es lo importante). Pero como C y A::B son la misma clase, obviamente no puede ser anidada ni anidada . La única conclusión lógica es que la clase en sí no está anidada.

La característica definitoria de las clases anidadas es que la búsqueda de métodos se realiza a lo largo de dos dimensiones: hacia arriba en la cadena de herencia y hacia afuera a través del anidamiento. Ruby, como el 99.9% de todos los idiomas OO, solo admite el primero. (En cierto sentido, las clases anidadas heredan no solo las características de su superclase, sino también las características de la clase que las rodea).


Si desea que la clase anidada extienda la clase externa, entonces hágalo:

class Outer class Inner < Outer def use_outer_method outer_method("hi mom!") end end def outer_method(foo) puts foo end end foo = Outer::Inner.new foo.use_outer_method #<= "hi mom" foo.outer_method("hi dad!") #<= "hi dad"