Issue #4352 has been updated by Yusuke Endoh.

Assignee changed from Yusuke Endoh to Yukihiro Matsumoto

Hi, matz

This ticket includes some design concerns.

The source_location seems important information not only for
human users, but also for tools, such as a debugger, lint,
coverage measurement, etc.
James and Rocky seem to be interested in the aspect of tools,
and dislike eval, which fakes the information.


1) Is the feature that fakes source_location really needed?
I guess that the feature is designed for erb-like application,
but C-style "#line" may be better.

2) What source_location should be used when only binding is
given?

  eval("__FILE__", TOPLEVEL_BINDING) #=> "<main>" or "(eval)"?

Some people expect "<main>" [ruby-dev:38767], and others expect
"(eval)".  [ruby-core:35027]

3) Which source_location should be used when binding and
explicit source_location are both given?

  eval("__FILE__", TOPLEVEL_BINDING, "foo") #=> "<main>" or "foo"?

Currently "foo" is returned.

4) Should 3) be applied even if "(eval)" is given explicitly?

  eval("__FILE__", TOPLEVEL_BINDING, "(eval)") #=> "<main>" or "(eval)"?

Currently "<main>" is returned.

5) Shouldn't ruby have two-type information, one for human and
one for tools?  The former is used for backtrace.  The latter
is used for tools.  eval can fake only the former information.

6) If 5) is accepted, which information should be used by
require_relative?  See #4487.


Thanks,
-- 
Yusuke Endoh <mame / tsg.ne.jp>
----------------------------------------
Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)
http://redmine.ruby-lang.org/issues/4352

Author: James M. Lawrence
Status: Assigned
Priority: Normal
Assignee: Yukihiro Matsumoto
Category: core
Target version: 1.9.x
ruby -v: ruby 1.9.3dev (2011-02-01 trunk 30751) [i386-darwin9.8.0]


=begin
 def ex_message
   begin
     yield
   rescue => e
     p e.message
   end
 end
 
 ex_message { eval('raise') }
 ex_message { eval('raise', binding) }
 
 eval('def f ; end')
 p method(:f).source_location
 eval('def g ; end', binding)
 p method(:g).source_location
 ----
 Without patch:
 "(eval):1:in `block in <main>': "
 ""
 ["(eval)", 1]
 ["eval_test.rb", 14]
 
 With patch:
 "(eval):1:in `block in <main>': "
 "(eval):1:in `block in <main>': "
 ["(eval)", 1]
 ["(eval)", 1]
 
 Knowing the line of an error inside eval is useful. Passing a binding
 shouldn't discard that information. Present behavior is even wrong:
 there's no line 10 in this file.
 ----
 eval %{
   
   # .. code ...
   raise
 
 
 }, binding
 ----
 Without patch:
 /Users/jlawrence/tmp/raiser.rb:10:in `<main>': unhandled exception
 	from /Users/jlawrence/tmp/raiser.rb:7:in `eval'
 	from /Users/jlawrence/tmp/raiser.rb:7:in `<main>'
 
 With patch:
 /Users/jlawrence/tmp/raiser.rb:7:in `eval': (eval):4:in `<main>':  (RuntimeError)
 	from /Users/jlawrence/tmp/raiser.rb:7:in `eval'
 	from /Users/jlawrence/tmp/raiser.rb:7:in `<main>'
=end



-- 
http://redmine.ruby-lang.org