method_source icon indicating copy to clipboard operation
method_source copied to clipboard

Shouldn't `source` method work with `eval` ?

Open yanyingwang opened this issue 10 years ago • 2 comments

This is a test case to demonstrate what I mentioned in the title:

#!/usr/bin/env ruby
# test.rb

class TestClass
  source = <<-EOF
  def test_m
    "test_m here"
  end
  EOF

  eval(source)
end

[1] pry(main)> require './test.rb'                                                                                                                                                                                                                                      
=> true
[2] pry(main)> TestClass.new.test_m                                                                                                                                                                                                                                     
=> "test_m here"
[3] pry(main)> m  = TestClass.new.method :test_m                                                                                                                                                                                                                        
=> #<Method: TestClass#test_m>

[4] pry(main)> m.source                                                                                                                                                                                                                                                 
MethodSource::SourceNotFoundError: Could not load source for : No such file or directory @ rb_sysopen - (eval)
from /home/yanying/.rvm/gems/ruby-2.1.5/gems/method_source-0.8.2/lib/method_source.rb:55:in `rescue in lines_for'

[5] pry(main)> m.source_location                                                                                                                                                                                                                                        
=> ["(eval)", 1]
[6] pry(main)>      

yanyingwang avatar Nov 11 '15 08:11 yanyingwang

There's no way to read source code from eval.

kyrylo avatar Nov 11 '15 08:11 kyrylo

The live_ast gem does something like this. Here's a quick proof-of-concept to work with method_source:

require 'method_source'

@store = {}

def store src
  key = "(eval@#{src.hash})"
  @store[key] = src
  key
end

def source_eval src, bnd, *rest
  key = store src
  eval src, bnd, key, 1
end

source_eval <<-END, binding
def bar
  puts 'FOO'
end

def foo
  puts 'BAR'
end
END

f = method(:foo)
key, line = *f.source_location

p MethodSource.expression_at(@store[key], line)

A real implementation would need to override eval and use binding_of_caller to automate this.

mvz avatar May 04 '16 00:05 mvz