[#35027] [Ruby 1.9-Bug#4352][Open] [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s) — "James M. Lawrence" <redmine@...>

Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)

16 messages 2011/02/01

[#35114] [Ruby 1.9-Bug#4373][Open] http.rb:677: [BUG] Segmentation fault — Christian Fazzini <redmine@...>

Bug #4373: http.rb:677: [BUG] Segmentation fault

59 messages 2011/02/06

[#35171] [Ruby 1.9-Bug#4386][Open] encoding: directive does not affect regex expressions — mathew murphy <redmine@...>

Bug #4386: encoding: directive does not affect regex expressions

9 messages 2011/02/09

[#35237] [Ruby 1.9-Bug#4400][Open] nested at_exit hooks run in strange order — Suraj Kurapati <redmine@...>

Bug #4400: nested at_exit hooks run in strange order

12 messages 2011/02/15

[ruby-core:35038] Re: [Ruby 1.9-Bug#4352][Open] [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)

From: Yusuke ENDOH <mame@...>
Date: 2011-02-02 03:46:10 UTC
List: ruby-core #35038
Hi,

2011/2/1 James M. Lawrence <redmine@ruby-lang.org>:
> Knowing the line of an error inside eval is useful. Passing a binding
> shouldn't discard that information.


I understand you, but the behavior is intended.

A binding also has its own information of filename and lineno.
Some people ([ruby-core:28307] [ruby-dev:38767]) think that binding's
lineno information is more important than eval's information, and that
eval shouldn't discard the binding's informantion.

  # foo.rb
  eval("p [__FILE__, __LINE__]", binding)  #=> expected: ["foo.rb", 2]

In addition, the behavior is compatible to 1.8.


> 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>'


It is indeed confusing, but it can be understood as follows:

1) Here are actual linenos.  The binding has its own lineno at which the
method is called:

1: eval %{
2:
3:   # .. code ...
4:   raise
5:
6:
7: }, binding

2) binding virtually overwrites linenos so that the eval'ing code starts
with the binding's own lineno (that is, Line 7):

1: eval %{          # ( 7)
2:                  # ( 8)
3:   # .. code ...  # ( 9)
4:   raise          # (10)
5:                  # (11)
6:                  # (12)
7: }, binding       # (13)

3) an exception is raised at (virtual) Line 10.


You can exploit this behavior to know the lineno more directly:

 1: # foo.rb
 2: b, s = binding, %{
 3:
 4:
 5:   # .. code ...
 6:   raise           # <- HERE!!
 7:
 8:
 9: }, b
10: eval s, b #=> foo.rb:6:in `<main>': unhandled exception

I guess eval should have received binding as the first argument ;-)

  eval binding, %{
    ...
  }

-- 
Yusuke Endoh <mame@tsg.ne.jp>

In This Thread