class C1
def pr
puts 'C1'
end
end
class C2 < C1
def pr
puts 'C2'
super
puts self.method(:pr).source_location
end
end
c = C2.new
c.pr
In the program above is it possible to obtain location of the code executed by super
(C1::pr
in our case) as well as we obtain the location of C2::pr
code using source_location
method?
From ruby 2.2 you can use super_method
like this:
Class A
def pr
puts "pr"
end
end
Class B < A
def pr
puts "Super method: #{method(:pr).super_method}"
end
end
As super_method
returns a Method, you can chain them to find the ancestor:
def ancestor(m)
m = method(m) if m.is_a? Symbol
super_m = m.super_method
if super_m.nil?
return m
else
return ancestor super_m
end
end
You just have to get to the superclass, then use instance_method
to get the method from the superclass.
class C2 < C1
def pr
puts "C2"
super
puts "Child: #{self.method(:pr).source_location}"
puts "Parent: #{self.class.superclass.instance_method(:pr).source_location}"
end
end
EDIT—regarding the comment about checking the ancestry chain, it (surprisingly) seems to be unnecessary.
class C1
def pr
puts "C1"
end
end
class C2 < C1; end
class C3 < C2
def pr
puts "C3"
super
puts "Child source location: #{self.method(:pr).source_location}"
puts "Parent source location: #{self.class.superclass.instance_method(:pr).source_location}"
end
end
c = C3.new
c.pr
prints
C3
C1
Child source location: ["source_location.rb", 10]
Parent source location: ["source_location.rb", 2]
As per @bukk530, super_method
gets you what you want but a good way to access it via the console is
ClassName.new.method(:method_name).super_method.source_location
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