¿Cómo determinar la clase en que se definió un método?

Me gustaría determinar dinámicamente la clase en la que se definió el método actual.

Aquí hay un ejemplo estático de lo que estoy tratando de hacer:

class A def foo puts "I was defined in A" end end class B < A def foo puts "I was defined in B" super end end A.new.foo # I was defined in A B.new.foo # I was defined in B # I was defined in A <- this is the tricky one 

¿Cómo puedo reemplazar A y B en las cadenas anteriores con una expresión dinámica?

Aparentemente, #{self.class} no funciona. (se imprimiría I was defined in B dos veces para B )

Sospecho que la respuesta es “no puedes” , pero tal vez estoy pasando por alto algo.

Que hay de esto

 class A def foo puts "I was defined in #{Module.nesting.first}" end end class B < A def foo puts "I was defined in #{Module.nesting.first}" super end end 

Corregido siguiendo la sugerencia de WandMaker.

Usted podría utilizar Module.nesting.first .

Sin embargo, tenga en cuenta que esto funciona de manera puramente léxica, de la misma manera en que funciona la resolución de las constantes, por lo que no se reducirá si tiene necesidades más dinámicas:

 Foo = Class.new do def foo Module.nesting end end Foo.new.foo # => [] 

Tengo la molesta sensación de que si pudieras hacer esto, violaría la encapsulación orientada a objetos, aunque no puedo decir exactamente por qué. Entonces, no debería ser una sorpresa que sea difícil.

Puedo ver una forma si está abierto a modificar las definiciones de métodos:

 class A this = self define_method(:foo) do puts "I was defined in #{this}" end end class B < A this = self define_method(:foo) do puts "I was defined in #{this}" super() end end A.new.foo # I was defined in A B.new.foo # I was defined in B # I was defined in A