From: Yusuke ENDOH Date: 2011-02-02T12:46:10+09:00 Subject: [ruby-core:35038] Re: [Ruby 1.9-Bug#4352][Open] [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s) Hi, 2011/2/1 James M. Lawrence : > 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 `
': unhandled exception > from /Users/jlawrence/tmp/raiser.rb:7:in `eval' > from /Users/jlawrence/tmp/raiser.rb:7:in `
' > > With patch: > /Users/jlawrence/tmp/raiser.rb:7:in `eval': (eval):4:in `
': ?(RuntimeError) > from /Users/jlawrence/tmp/raiser.rb:7:in `eval' > from /Users/jlawrence/tmp/raiser.rb:7:in `
' 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 `
': unhandled exception I guess eval should have received binding as the first argument ;-) eval binding, %{ ... } -- Yusuke Endoh