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