I would like to dynamically determine the class the current method was defined in.
Here's 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 can I replace A and B in the strings above with a dynamic expression?
Apparently, #{self.class} does not work. (it would print I was defined in B twice for B)
I suspect that the answer is "you can't", but maybe I'm overlooking something.
What 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
Corrected following WandMaker's suggestion.
You could use Module.nesting.first.
However, note that this works purely lexically, the same way constants resolution works, so it won't cut it if you have more dynamic needs:
Foo = Class.new do
def foo
Module.nesting
end
end
Foo.new.foo # => []
I have this nagging feeling that if you could do this, it would violate object-orientated encapsulation, although I can't quite place my finger on exactly why. So, it shouldn't come as a surprise that it's hard.
I can see a way if you are open to modifying 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With