How to determine the class in which the method was defined?

I would like to dynamically determine the class in which the current method was defined.

Here is a static example of what I'm trying to do:

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 

How to replace A and B in the above lines with a dynamic expression?

Apparently, #{self.class} not working. (he will print I was defined in B twice for B )

I suspect the answer is “you can't,” but maybe I'm missing something.

+6
source share
3 answers

How about this?

 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 

The following WandMaker sentence has been fixed.

+4
source

You can use Module.nesting.first .

However, note that this works exclusively lexically, just as constant resolution works, so it won’t shorten it if you have more dynamic needs:

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

I have this nagging feeling that if you could do it, it would violate object-oriented encapsulation, although I cannot say why. Therefore, it should not be surprising that it is difficult.

I see a way if you can change the method definitions:

 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 
+3
source

All Articles