https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112011-02-02T05:35:02ZRuby Issue Tracking SystemRuby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=156352011-02-02T05:35:02Zquix (James M. Lawrence)quixoticsycophant@gmail.com
<ul></ul><p>I came across this issue when I noticed that source_location gives non-useful info when a binding is passed to eval. Thus the patch fixes two somewhat different problems: eval backtrace and source_location. If changing the backtrace is inappropriate then a separate bug for source_location should be filed.</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=156392011-02-02T12:46:44Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>Hi,</p>
<p>2011/2/1 James M. Lawrence <a href="mailto:redmine@ruby-lang.org" class="email">redmine@ruby-lang.org</a>:</p>
<blockquote>
<p>Knowing the line of an error inside eval is useful. Passing a binding<br>
shouldn't discard that information.</p>
</blockquote>
<p>I understand you, but the behavior is intended.</p>
<p>A binding also has its own information of filename and lineno.<br>
Some people (<a href="/issues/2782">[ruby-core:28307]</a> <a href="/issues/1769">[ruby-dev:38767]</a>) think that binding's<br>
lineno information is more important than eval's information, and that<br>
eval shouldn't discard the binding's informantion.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># foo.rb</span>
<span class="nb">eval</span><span class="p">(</span><span class="s2">"p [__FILE__, __LINE__]"</span><span class="p">,</span> <span class="nb">binding</span><span class="p">)</span> <span class="c1">#=> expected: ["foo.rb", 2]</span>
</code></pre>
<p>In addition, the behavior is compatible to 1.8.</p>
<blockquote>
<p>Present behavior is even wrong:<br>
there's no line 10 in this file.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">eval</span> <span class="sx">%{
# .. code ...
raise
}</span><span class="p">,</span> <span class="nb">binding</span>
</code></pre>
<p>Without patch:</p>
<pre><code>/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>'
</code></pre>
<p>With patch:</p>
<pre><code>/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>'
</code></pre>
</blockquote>
<p>It is indeed confusing, but it can be understood as follows:</p>
<ol>
<li>Here are actual linenos. The binding has its own lineno at which the<br>
method is called:</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mi">1</span><span class="p">:</span> <span class="nb">eval</span> <span class="sx">%{
2:
3: # .. code ...
4: raise
5:
6:
7: }</span><span class="p">,</span> <span class="nb">binding</span>
</code></pre>
<ol start="2">
<li>binding virtually overwrites linenos so that the eval'ing code starts<br>
with the binding's own lineno (that is, Line 7):</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mi">1</span><span class="p">:</span> <span class="nb">eval</span> <span class="sx">%{ # ( 7)
2: # ( 8)
3: # .. code ... # ( 9)
4: raise # (10)
5: # (11)
6: # (12)
7: }</span><span class="p">,</span> <span class="nb">binding</span> <span class="c1"># (13)</span>
</code></pre>
<ol start="3">
<li>an exception is raised at (virtual) Line 10.</li>
</ol>
<p>You can exploit this behavior to know the lineno more directly:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="mi">1</span><span class="p">:</span> <span class="c1"># foo.rb</span>
<span class="mi">2</span><span class="p">:</span> <span class="n">b</span><span class="p">,</span> <span class="n">s</span> <span class="o">=</span> <span class="nb">binding</span><span class="p">,</span> <span class="sx">%{
3:
4:
5: # .. code ...
6: raise # <- HERE!!
7:
8:
9: }</span><span class="p">,</span> <span class="n">b</span>
<span class="mi">10</span><span class="p">:</span> <span class="nb">eval</span> <span class="n">s</span><span class="p">,</span> <span class="n">b</span> <span class="c1">#=> foo.rb:6:in `<main>': unhandled exception</span>
</code></pre>
<p>I guess eval should have received binding as the first argument ;-)</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">eval</span> <span class="nb">binding</span><span class="p">,</span> <span class="sx">%{
...
}</span>
</code></pre>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=156412011-02-02T14:36:09Zquix (James M. Lawrence)quixoticsycophant@gmail.com
<ul></ul><p>Thank you for that detailed explanation. The problem for me is the<br>
connection to <code>source_location</code>, which should be usable by tools.</p>
<p>Shouldn't <code>source_location</code> give the file and line of a method or block<br>
definition? If so then <code>source_location</code> is bugged when the binding<br>
argument is passed.</p>
<p>The seemingly simplest solution is to make the backtrace and<br>
<code>source_location</code> consistent. It only takes a 4-line patch.</p>
<p>I might have thought otherwise if virtual line numbers served some<br>
human purpose, but I just see them as confusing. Tools are even more<br>
confused.</p>
<p>Should a new bug for source_location be created?</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=156462011-02-03T00:48:14Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>Hi,</p>
<p>2011/2/2 James M. Lawrence <a href="mailto:redmine@ruby-lang.org" class="email">redmine@ruby-lang.org</a>:</p>
<blockquote>
<p>Thank you for that detailed explanation. The problem for me is the<br>
connection to <code>source_location</code>, which should be usable by tools.</p>
</blockquote>
<p>What kind of tools are you talking about?<br>
Even if a binding location is discarded, we can still fake <code>__FILE__</code><br>
and <code>__LINE__</code> without using a binding:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">eval</span> <span class="o"><<-</span><span class="no">END</span><span class="p">,</span> <span class="kp">nil</span><span class="p">,</span> <span class="s2">"/etc/passwd"</span><span class="p">,</span> <span class="mi">1</span><span class="sh">
def foo
end
</span><span class="no">END</span>
<span class="nb">p</span> <span class="nb">method</span><span class="p">(</span><span class="ss">:foo</span><span class="p">).</span><span class="nf">source_location</span> <span class="c1">#=> ["/etc/passwd", 1]</span>
</code></pre>
<p>So, <code>source_location</code> user should know and accept the fact that the<br>
information is not trustable.<br>
Why do you think only a binding location as a problem?</p>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=156592011-02-03T11:23:52Zquix (James M. Lawrence)quixoticsycophant@gmail.com
<ul></ul><blockquote>
<p>Why do you think only a binding location as a problem?</p>
</blockquote>
<p>The initial problem I encountered was</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">eval</span> <span class="sx">%{def g ; end}</span><span class="p">,</span> <span class="kp">nil</span><span class="p">,</span> <span class="s2">"(eval)"</span><span class="p">,</span> <span class="mi">99</span>
<span class="nb">p</span> <span class="nb">method</span><span class="p">(</span><span class="ss">:g</span><span class="p">).</span><span class="nf">source_location</span> <span class="c1">#=> ["(eval)", 99]</span>
<span class="nb">eval</span> <span class="sx">%{def f ; end}</span><span class="p">,</span> <span class="nb">binding</span><span class="p">,</span> <span class="s2">"(eval)"</span><span class="p">,</span> <span class="mi">99</span>
<span class="nb">p</span> <span class="nb">method</span><span class="p">(</span><span class="ss">:f</span><span class="p">).</span><span class="nf">source_location</span> <span class="c1">#=> ["prob.rb", 1]</span>
</code></pre>
<p>I needed <code>source_location</code> to be <code>["(eval)", 99]</code> in the latter case,<br>
which is solved by the patch. This could be also be done by making<br>
eval recognize the difference between an empty file argument and an<br>
<code>"(eval)"</code> file argument, however the problem seemed more fundamental.</p>
<p>eval should not implicitly slurp file/line info from the binding.<br>
Creating a "dishonest" backtrace is something that should be done<br>
explicitly by the user, as in</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">eval</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="o">*</span><span class="n">b</span><span class="p">.</span><span class="nf">source_location</span><span class="p">)</span>
</code></pre>
<p>In the last the example in the original post, the existence of<br>
raiser.rb:10 is an outright falsehood. Pointing to a nonexistent line<br>
number should not be the default behavior of <code>eval(s, b)</code>.</p>
<p>Since <code>source_location</code> claims to be "the ruby source filename and line<br>
number containing this proc", I was thinking that <code>source_location</code><br>
could give the "true" location, ignoring the file/line "lies" passed<br>
to eval. But this was wrong--indeed I want the "lies" to be reflected<br>
in <code>source_location</code>. My problem is with eval implicitly grabbing<br>
file/line from the binding, which is just what the patch solves.</p>
<p>As mentioned above, this would be nice too:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Binding</span>
<span class="k">def</span> <span class="nf">source_location</span>
<span class="nb">eval</span> <span class="s2">"[__FILE__, __LINE__]"</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/proc.c b/proc.c
index 7b1d147..0042caf 100644
</span><span class="gd">--- a/proc.c
</span><span class="gi">+++ b/proc.c
</span><span class="p">@@ -305,6 +305,24 @@</span> binding_clone(VALUE self)
return bindval;
}
<span class="gi">+/*
+ * call-seq:
+ * binding.source_location -> [String, Fixnum]
+ *
+ * Returns the ruby source filename and line number associated with
+ * this binding.
+ */
+static VALUE
+binding_source_location(VALUE self)
+{
+ rb_binding_t *src;
+ VALUE loc[2];
+ GetBindingPtr(self, src);
+ loc[0] = rb_str_dup_frozen(src->filename);
+ loc[1] = INT2FIX(src->line_no);
+ return rb_ary_new4(2, loc);
+}
+
</span> VALUE
rb_binding_new(void)
{
<span class="p">@@ -2227,6 +2245,7 @@</span> Init_Binding(void)
rb_undef_method(CLASS_OF(rb_cBinding), "new");
rb_define_method(rb_cBinding, "clone", binding_clone, 0);
rb_define_method(rb_cBinding, "dup", binding_dup, 0);
<span class="gi">+ rb_define_method(rb_cBinding, "source_location", binding_source_location, 0);
</span> rb_define_method(rb_cBinding, "eval", bind_eval, -1);
rb_define_global_function("binding", rb_f_binding, 0);
}
</code></pre> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=156602011-02-03T13:19:09Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>Hi,</p>
<p>2011/2/3 Rocky Bernstein <a href="mailto:rockyb@rubyforge.org" class="email">rockyb@rubyforge.org</a>:</p>
<blockquote>
<p>See also<br>
<a href="http://ola-bini.blogspot.com/2008/01/ruby-antipattern-using-eval-without.html" class="external">http://ola-bini.blogspot.com/2008/01/ruby-antipattern-using-eval-without.html</a>.<br>
It is called an "anti-pattern" there which I guess is used in a derogatory<br>
fashion.</p>
</blockquote>
<p>I'd like to positively call it a "best practice" :-)</p>
<blockquote>
<p>A place where setting the file and line is used is in template systems like<br>
merb or erb where the file the user works on is not a Ruby file but a<br>
template file that expands to a Ruby file. In that situation, disregarding<br>
the expanded Ruby file is convenient since there can only be one location<br>
attached in the Ruby implementation.<br>
However I don't see why a templating system couldn't also provide an<br>
expanded Ruby file for debugging problems much as one can get the<br>
C-preprocessed output for a C program when one wants.</p>
</blockquote>
<p>I'm not sure that I could understand you.<br>
Are you saying that erb users should debug their erb code by looking<br>
the erb-generated Ruby code? I don't think that it is user-friendly.</p>
<p>FYI, erb offers <code>ERB#src</code> which provides a generated Ruby code. However,<br>
I don't want to encourage users to read and debug the generated code.</p>
<blockquote>
<p>But shouldn't we try to address the location problem head on in the Ruby<br>
implementation? I suspect it too late to try to change Ruby MRI 1.x, but<br>
perhaps in Ruby 2.x some thought could be given to how to address.?</p>
</blockquote>
<p>Yes, it is good to improve the spec in 2.0.<br>
Before that, we must first check the use case.<br>
For creating what kind of tools, what kind of information do you need?</p>
<blockquote>
<p>If the fact that <code>source_location</code> is not trustable is a a concern, then<br>
perhaps setting the file and line parameters on eval can be disallowed at<br>
some level greater than 0 and less than 4 which is where <code>eval()</code> is<br>
disallowed totally.?</p>
</blockquote>
<p>We should not ignore erb-like use case. Just prohibiting the file and<br>
line parameters is too strict. Unless Ruby provides an alternative<br>
feature, like <code>#line</code> of C-preprocessor.</p>
<p>BTW, is it ok for you that <code>source_location</code> returns <code>["(eval)", 1]</code>?<br>
It does not allow to distinguish whether it is executed in <code>Kernel#eval</code><br>
or the source code file is named <code>"(eval)"</code>.<br>
<code>"-"</code> (for stdin) and <code>"-e"</code> (for -e option) seem to have the same problem.</p>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=156612011-02-03T13:19:40Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>Hi,</p>
<p>2011/2/3 James M. Lawrence <a href="mailto:redmine@ruby-lang.org" class="email">redmine@ruby-lang.org</a>:</p>
<blockquote>
<p>The initial problem I encountered was</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">eval</span> <span class="sx">%{def g ; end}</span><span class="p">,</span> <span class="kp">nil</span><span class="p">,</span> <span class="s2">"(eval)"</span><span class="p">,</span> <span class="mi">99</span>
<span class="nb">p</span> <span class="nb">method</span><span class="p">(</span><span class="ss">:g</span><span class="p">).</span><span class="nf">source_location</span> <span class="c1">#=> ["(eval)", 99]</span>
<span class="nb">eval</span> <span class="sx">%{def f ; end}</span><span class="p">,</span> <span class="nb">binding</span><span class="p">,</span> <span class="s2">"(eval)"</span><span class="p">,</span> <span class="mi">99</span>
<span class="nb">p</span> <span class="nb">method</span><span class="p">(</span><span class="ss">:f</span><span class="p">).</span><span class="nf">source_location</span> <span class="c1">#=> ["prob.rb", 1]</span>
</code></pre>
</blockquote>
<p>Hmm. It is indeed irritating for <code>Kernel#eval</code> to prefer implicit filename<br>
of a binding to explicitly-specified filename.<br>
This is because the current implementation is uncool, like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">eval</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="nb">binding</span><span class="p">,</span> <span class="n">filename</span> <span class="o">=</span> <span class="s2">"(eval)"</span><span class="p">,</span> <span class="n">lineno</span> <span class="o">=</span> <span class="mi">1</span><span class="p">)</span>
<span class="n">filename</span> <span class="o">=</span> <span class="nb">binding</span><span class="p">.</span><span class="nf">filename</span> <span class="k">if</span> <span class="n">filename</span> <span class="o">==</span> <span class="s2">"(eval)"</span>
<span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p><code>Kernel#eval</code> uses a string <code>"(eval)"</code> when the filename is not specified<br>
explicitly. And then, it replaces it with implicit filename of binding<br>
when the given filename is equal to <code>"(eval)"</code> with string comparison.</p>
<p>Even so, I hesitate to change the behavior in 1.9.x for compatibility<br>
reason.</p>
<blockquote>
<p>Since <code>source_location</code> claims to be "the ruby source filename and line<br>
number containing this proc", I was thinking that <code>source_location</code><br>
could give the "true" location, ignoring the file/line "lies" passed<br>
to eval.</p>
</blockquote>
<p>Honestly, I understand your expectation. It is of course acceptable to<br>
fix it in 2.0. But it would require a major modification because the<br>
current implementation itself does NOT know the "true" location. The<br>
information is discarded at the parse time.</p>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=156622011-02-03T13:57:29Zquix (James M. Lawrence)quixoticsycophant@gmail.com
<ul></ul><p>Yusuke Endoh:</p>
<blockquote>
<blockquote>
<p>Since source_location claims to be "the ruby source filename and line<br>
number containing this proc", I was thinking that <code>source_location</code><br>
could give the "true" location, ignoring the file/line "lies" passed<br>
to eval.</p>
</blockquote>
<p>Honestly, I understand your expectation. It is of course acceptable to<br>
fix it in 2.0. But it would require a major modification because the<br>
current implementation itself does NOT know the "true" location. The<br>
information is discarded at the parse time.</p>
</blockquote>
<p>Did you misunderstand? It's not my expectation--the next sentence said<br>
it was wrong, and indeed I rely on the current behavior.</p>
<p>My expectation is that overriding file/line for eval can only be done<br>
explicitly, never implicitly through the binding. That's what the<br>
patch does. What did you think of my argument for that?</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=156672011-02-04T09:21:20Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>Hi,</p>
<p>2011/2/3 James M. Lawrence <a href="mailto:redmine@ruby-lang.org" class="email">redmine@ruby-lang.org</a>:</p>
<blockquote>
<p>Yusuke Endoh:</p>
<blockquote>
<blockquote>
<p>Since source_location claims to be "the ruby source filename and line<br>
number containing this proc", I was thinking that <code>source_location</code><br>
could give the "true" location, ignoring the file/line "lies" passed<br>
to eval.</p>
</blockquote>
<p>Honestly, I understand your expectation. It is of course acceptable to<br>
fix it in 2.0. But it would require a major modification because the<br>
current implementation itself does NOT know the "true" location. The<br>
information is discarded at the parse time.</p>
</blockquote>
<p>Did you misunderstand? It's not my expectation--the next sentence said<br>
it was wrong, and indeed I rely on the current behavior.</p>
<p>My expectation is that overriding file/line for eval can only be done<br>
explicitly, never implicitly through the binding.</p>
</blockquote>
<p>I see. Sorry for my misunderstanding.<br>
But anyway, it is difficult to meet your expectation in 1.9.<br>
Inheriting file/line from a binding is actually intended, not a<br>
bug, even though it is confusing.<br>
We cannot change any spec in 1.9, unless it is considered a bug.</p>
<p>However, it might be considered a bug for <code>Kernel#eval</code> to ignore<br>
an explicitly specified <code>"(eval)"</code>, I think.</p>
<p>Does that answer you?</p>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=157262011-02-08T03:22:34Zquix (James M. Lawrence)quixoticsycophant@gmail.com
<ul></ul><p>Yusuke Endoh:</p>
<blockquote>
<p>However, it might be considered a bug for <code>Kernel#eval</code> to ignore<br>
an explicitly specified <code>"(eval)"</code>, I think.</p>
<p>Does that answer you?</p>
</blockquote>
<p>Yes, thanks. Redmine doesn't have a category for bugs that are fixed<br>
by a feature request :). As Rocky explains there are some deeper<br>
issues involved, but it still amounts to a feature request. I've filed<br>
a new bug for <code>"(eval)"</code> <a href="/issues/4379">[ruby-core:35139]</a>. Sorry for the confusion.</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=183992011-06-26T17:35:57Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>mame (Yusuke Endoh)</i></li></ul> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=188272011-07-05T12:50:30Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Assignee</strong> changed from <i>mame (Yusuke Endoh)</i> to <i>matz (Yukihiro Matsumoto)</i></li></ul><p>Hi, matz</p>
<p>This ticket includes some design concerns.</p>
<p>The source_location seems important information not only for<br>
human users, but also for tools, such as a debugger, lint,<br>
coverage measurement, etc.<br>
James and Rocky seem to be interested in the aspect of tools,<br>
and dislike eval, which fakes the information.</p>
<ol>
<li>
<p>Is the feature that fakes source_location really needed?<br>
I guess that the feature is designed for erb-like application,<br>
but C-style "<code>#line</code>" may be better.</p>
</li>
<li>
<p>What <code>source_location</code> should be used when only binding is<br>
given?</p>
</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">eval</span><span class="p">(</span><span class="s2">"__FILE__"</span><span class="p">,</span> <span class="no">TOPLEVEL_BINDING</span><span class="p">)</span> <span class="c1">#=> "<main>" or "(eval)"?</span>
</code></pre>
<p>Some people expect <code>"<main>"</code> <a href="/issues/1769">[ruby-dev:38767]</a>, and others expect<br>
<code>"(eval)"</code>. <a href="/issues/4352">[ruby-core:35027]</a></p>
<ol start="3">
<li>Which <code>source_location</code> should be used when binding and<br>
explicit <code>source_location</code> are both given?</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">eval</span><span class="p">(</span><span class="s2">"__FILE__"</span><span class="p">,</span> <span class="no">TOPLEVEL_BINDING</span><span class="p">,</span> <span class="s2">"foo"</span><span class="p">)</span> <span class="c1">#=> "<main>" or "foo"?</span>
</code></pre>
<p>Currently "foo" is returned.</p>
<ol start="4">
<li>Should 3) be applied even if <code>"(eval)"</code> is given explicitly?</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">eval</span><span class="p">(</span><span class="s2">"__FILE__"</span><span class="p">,</span> <span class="no">TOPLEVEL_BINDING</span><span class="p">,</span> <span class="s2">"(eval)"</span><span class="p">)</span> <span class="c1">#=> "<main>" or "(eval)"?</span>
</code></pre>
<p>Currently <code>"<main>"</code> is returned. (7th Dec. 2017: now it returns <code>"(eval)"</code>.)</p>
<ol start="5">
<li>
<p>Shouldn't ruby have two-type information, one for human and<br>
one for tools? The former is used for backtrace. The latter<br>
is used for tools. eval can fake only the former information.</p>
</li>
<li>
<p>If 5) is accepted, which information should be used by<br>
require_relative? See <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: require_relative fails in an eval'ed file (Closed)" href="https://bugs.ruby-lang.org/issues/4487">#4487</a>.</p>
</li>
</ol>
<p>Thanks,</p>
<hr>
<p>Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=364022013-02-17T15:22:56Zko1 (Koichi Sasada)
<ul><li><strong>Target version</strong> changed from <i>2.0.0</i> to <i>2.1.0</i></li></ul><p>Time up for 2.0.0.</p>
<p>Matz, could you check this ticket?</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=447372014-01-30T06:16:28Zhsbt (Hiroshi SHIBATA)hsbt@ruby-lang.org
<ul><li><strong>Target version</strong> changed from <i>2.1.0</i> to <i>2.2.0</i></li></ul> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=683152017-12-12T09:05:44Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul><li><strong>Target version</strong> changed from <i>2.2.0</i> to <i>2.6</i></li></ul><p>I am sorry I missed this issue for a long time.</p>
<p>I agree with the rationale behind the proposal. I am slightly concerned about incompatibility.<br>
So we need to experiment to measure how big the compatibility issue after changing the behavior.<br>
I expect the impact is small (but my expectation fails often).</p>
<p>Matz.</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=683512017-12-12T23:41:22Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Assignee</strong> changed from <i>matz (Yukihiro Matsumoto)</i> to <i>mame (Yusuke Endoh)</i></li></ul><p>Thank you, matz.<br>
I'll try this change after 2.5 is released.</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=686352017-12-25T09:44:57Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Assignee</strong> changed from <i>mame (Yusuke Endoh)</i> to <i>matz (Yukihiro Matsumoto)</i></li></ul><p>matz (Yukihiro Matsumoto) wrote:</p>
<blockquote>
<p>I agree with the rationale behind the proposal. I am slightly concerned about incompatibility.<br>
So we need to experiment to measure how big the compatibility issue after changing the behavior.<br>
I expect the impact is small (but my expectation fails often).</p>
</blockquote>
<p>I tried the change, and found some projects actually use the idiom, <code>eval("[__FILE__, __LINE__]", binding)</code>, to fetch the source location. See <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Binding#source_location (Closed)" href="https://bugs.ruby-lang.org/issues/14230">#14230</a> in detail. What should we do?</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=686712017-12-25T18:14:59Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Target version</strong> deleted (<del><i>2.6</i></del>)</li></ul> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=689972017-12-26T17:39:43Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Target version</strong> set to <i>2.7</i></li></ul><p>We discussed this issue at today's Ruby committer's meeting. We can't change the behavior soon because of compatibility issue, so we need a transition path.</p>
<p>After r61483, a warning is now printed when <code>eval</code> receives only <code>binding</code> and the code includes <code>__FILE__</code> or <code>__LINE__</code>.</p>
<pre><code>$ ./miniruby -w -e 'eval("[__FILE__, __LINE__]", binding)'
-e:1: warning: __FILE__ in eval may not return location in binding; use Binding#source_location instead
-e:1: warning: __LINE__ in eval may not return location in binding; use Binding#source_location instead
</code></pre>
<p>The return value will be changed from binding's source location to eval's default, i.e., <code>"(eval)"</code> and <code>1</code>. If you need the traditional behavior, please pass the location information explicitly, like: <code>eval("[__FILE__, __LINE__]", binding, *binding.source_location)</code>.</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=721722018-05-18T23:28:57Zxuhuan587 (环 徐)
<ul><li><strong>File</strong> deleted (<del><i>eval.patch</i></del>)</li></ul> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=803122019-07-31T18:41:38Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>File</strong> <a href="/attachments/7924">eval-binding-file-line-4352.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/7924/eval-binding-file-line-4352.patch">eval-binding-file-line-4352.patch</a> added</li></ul><p>Attached is a patch to remove the warning and change the behavior, as well as update the tests and specs so that <code>eval("[__FILE__, __LINE__]", binding)</code> returns <code>["(eval)", 1]</code>.</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=803522019-08-02T14:17:41Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li></ul><p>Applied in changeset <a class="changeset" title="parse.y: make a warning for __FILE__ in eval by default [Bug #4352]" href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/e9e17cbc051e894dfd27eda5feca2939f65552db">git|e9e17cbc051e894dfd27eda5feca2939f65552db</a>.</p>
<hr>
<p>parse.y: make a warning for <strong>FILE</strong> in eval by default</p>
<p>[Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s) (Closed)" href="https://bugs.ruby-lang.org/issues/4352">#4352</a>]</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=803532019-08-02T14:21:00Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Closed</i> to <i>Open</i></li><li><strong>Target version</strong> changed from <i>2.7</i> to <i>3.0</i></li></ul><p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/1604">@jeremyevans0 (Jeremy Evans)</a> , thank you for reminding this issue.</p>
<p>The warning is printed only on the verbose mode in 2.6. It would be good to enable the warning by default in 2.7.<br>
I tentatively changed at e9e17cbc051e894dfd27eda5feca2939f65552db. How about applying your patch for 3.0?<br>
If you think your patch should be applied soon, I'm not so strongly against it.</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=803542019-08-02T15:11:13Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>mame (Yusuke Endoh) wrote:</p>
<blockquote>
<p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/1604">@jeremyevans0 (Jeremy Evans)</a> , thank you for reminding this issue.</p>
<p>The warning is printed only on the verbose mode in 2.6. It would be good to enable the warning by default in 2.7.<br>
I tentatively changed at e9e17cbc051e894dfd27eda5feca2939f65552db. How about applying your patch for 3.0?<br>
If you think your patch should be applied soon, I'm not so strongly against it.</p>
</blockquote>
<p><a class="user active user-mention" href="https://bugs.ruby-lang.org/users/18">@mame (Yusuke Endoh)</a> I think applying my patch for 3.0 is fine. I only suggested it for 2.7 because that is what the issue target was.</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=803612019-08-02T22:48:15Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>Applied in changeset <a class="changeset" title="Use source_location instead of eval(__FILE__,binding) in Binding#irb e9e17cbc051e894dfd27eda5fec..." href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/c6837638657429034825d5c9e2a29c340898afb8">git|c6837638657429034825d5c9e2a29c340898afb8</a>.</p>
<hr>
<p>Use source_location instead of eval(<strong>FILE</strong>,binding) in Binding#irb</p>
<p>e9e17cbc051e894dfd27eda5feca2939f65552db (enabling the warning by<br>
default) caused a warning in test-spec:</p>
<pre><code>/data/chkbuild/tmp/build/20190802T213005Z/ruby/spec/ruby/core/binding/irb_spec.rb
Binding#irb
- creates an IRB session with the binding in scope/data/chkbuild/tmp/build/20190802T213005Z/ruby/spec/ruby/core/binding/fixtures/irb.rb:3: warning: __FILE__ in eval may not return location in binding; use Binding#source_location instead
</code></pre>
<p><a href="https://rubyci.org/logs/rubyci.s3.amazonaws.com/debian/ruby-master/log/20190802T213005Z.log.html.gz" class="external">https://rubyci.org/logs/rubyci.s3.amazonaws.com/debian/ruby-master/log/20190802T213005Z.log.html.gz</a></p>
<p>ref: [Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s) (Closed)" href="https://bugs.ruby-lang.org/issues/4352">#4352</a>]</p> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=806662019-08-12T23:06:32Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>Status</strong> changed from <i>Closed</i> to <i>Open</i></li></ul> Ruby master - Bug #4352: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s)https://bugs.ruby-lang.org/issues/4352?journal_id=836182020-01-04T04:13:32Zjeremyevans (Jeremy Evans)code@jeremyevans.net
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>Applied in changeset <a class="changeset" title="Make eval(code, binding) use (eval) as __FILE__ and 1 as __LINE__ This removes the warning that ..." href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/0eeed5bcc5530edb0af2af2ccff09d067c59e8f9">git|0eeed5bcc5530edb0af2af2ccff09d067c59e8f9</a>.</p>
<hr>
<p>Make eval(code, binding) use (eval) as <strong>FILE</strong> and 1 as <strong>LINE</strong></p>
<p>This removes the warning that was added in<br>
3802fb92ff8c83eed3e867db20f72c53932f542d, and switches the behavior<br>
so that the eval does not use the binding's <strong>FILE</strong> and <strong>LINE</strong><br>
implicitly.</p>
<p>Fixes [Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: [patch] Fix eval(s, b) backtrace; make eval(s, b) consistent with eval(s) (Closed)" href="https://bugs.ruby-lang.org/issues/4352">#4352</a>]</p>