diff options
author | John Mair <jrmair@gmail.com> | 2011-02-28 03:40:47 +1300 |
---|---|---|
committer | John Mair <jrmair@gmail.com> | 2011-02-28 03:40:47 +1300 |
commit | 52ef85631d136a4ff31c0f4c2587b19db3daf512 (patch) | |
tree | fcad597e22e22a576fd6ac74b878e89785012d67 /lib/method_source/source_location.rb | |
parent | 8f6b36637263a79ae4ac96ec734b1851614a4e19 (diff) | |
download | method_source-dev.tar.gz |
version 0.3.0, some ruby 1.8 supportdev
Diffstat (limited to 'lib/method_source/source_location.rb')
-rw-r--r-- | lib/method_source/source_location.rb | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/lib/method_source/source_location.rb b/lib/method_source/source_location.rb new file mode 100644 index 0000000..1878b18 --- /dev/null +++ b/lib/method_source/source_location.rb @@ -0,0 +1,56 @@ +module MethodSource + module SourceLocation + module MethodExtensions + def trace_func(event, file, line, id, binding, classname) + return unless event == 'call' + set_trace_func nil + + @file, @line = file, line + raise :found + end + + # Return the source location of a method for Ruby 1.8. + # @return [Array] A two element array. First element is the + # file, second element is the line in the file where the + # method definition is found. + def source_location + if @file.nil? + args =[*(1..(arity<-1 ? -arity-1 : arity ))] + + set_trace_func method(:trace_func).to_proc + call *args rescue nil + set_trace_func nil + @file = File.expand_path(@file) if @file && File.exist?(File.expand_path(@file)) + end + return [@file, @line] if File.exist?(@file.to_s) + end + end + + module UnboundMethodExtensions + + # Return the source location of an instance method for Ruby 1.8. + # @return [Array] A two element array. First element is the + # file, second element is the line in the file where the + # method definition is found. + def source_location + klass = case owner + when Class + owner + when Module + Class.new.tap { |v| v.send(:include, owner) } + end + + begin + klass.allocate.method(name).source_location + rescue TypeError + + # Assume we are dealing with a Singleton Class: + # 1. Get the instance object + # 2. Forward the source_location lookup to the instance + instance ||= ObjectSpace.each_object(owner).first + instance.method(name).source_location + end + end + end + end +end |