https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112019-09-27T23:00:34ZRuby Issue Tracking SystemRuby master - Bug #16181: return from a proc in a module/class body returns out of script. Should be LJE.https://redmine.ruby-lang.org/issues/16181?journal_id=817772019-09-27T23:00:34Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>It looked into this behavior, which started in Ruby 2.4 (when top level return started being allowed).</p>
<p><code>return</code> not being allowed directly in class/module body is a parse error, because the parser knows that it cannot be valid. However, you cannot have the behavior inside of a block inside of class/module be a parse error, because you do not know how the block will be evaluated:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Foo</span>
<span class="k">alias</span> <span class="nb">proc</span> <span class="nb">lambda</span>
<span class="nb">proc</span> <span class="p">{</span> <span class="k">return</span> <span class="p">}.</span><span class="nf">call</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="s2">"NEVER SEEN"</span>
</code></pre>
<p>Similarly, though this operates as a top level return, the warning for top level return with argument does not take effect, because the compiler doesn't know it will operate as a top level return:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Foo</span>
<span class="nb">proc</span> <span class="p">{</span> <span class="k">return</span> <span class="mi">1</span> <span class="p">}.</span><span class="nf">call</span> <span class="c1"># no top level return with argument warning</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="s2">"NEVER SEEN"</span>
</code></pre>
<p>I don't think the compiler has enough information to handle this correctly, because it doesn't know at compilation time whether the block will be executed as a proc or as a lambda.</p>
<p>I do agree that a LocalJumpError is the most appropriate way to handle this.</p> Ruby master - Bug #16181: return from a proc in a module/class body returns out of script. Should be LJE.https://redmine.ruby-lang.org/issues/16181?journal_id=817952019-09-30T18:21:40Zenebo (Thomas Enebo)tom.enebo@gmail.com
<ul></ul><p>I agree this is impossible to be done by parser or at iseq generation time. It must be done when return is invoked.</p>
<p>JRuby will return LocalJumpError for this for 9.2.9.0. It also had from 9.2.6.0 and earlier.</p>
<p>As a runtime LJE we know lexically it is defined within a module/class and we can also look up stack to see if it has migrated or not (I assume MRI has even more flexibility in this than JRuby does). Similarly we know it is a lambda or not at that point so that is not really a problem at runtime.</p>
<p>Jeremy, since you are only person who has looked would you say semantically this should be some error vs silently only executing part of a file?</p> Ruby master - Bug #16181: return from a proc in a module/class body returns out of script. Should be LJE.https://redmine.ruby-lang.org/issues/16181?journal_id=817962019-09-30T18:32:58Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>enebo (Thomas Enebo) wrote:</p>
<blockquote>
<p>Jeremy, since you are only person who has looked would you say semantically this should be some error vs silently only executing part of a file?</p>
</blockquote>
<p>I believe if <code>return</code> directly inside <code>class</code>/<code>module</code> is an error, <code>return</code> inside <code>proc</code> inside <code>class</code>/<code>module</code> should also be an error. Since it cannot be a compile time error, it should be a runtime error (<code>LocalJumpError</code>).</p>
<p>Alternatively, we start to allow <code>return</code> inside <code>class</code>/<code>module</code>, and then the current behavior for <code>return</code> inside <code>proc</code> inside <code>class</code>/<code>module</code> makes sense.</p> Ruby master - Bug #16181: return from a proc in a module/class body returns out of script. Should be LJE.https://redmine.ruby-lang.org/issues/16181?journal_id=817982019-09-30T20:11:18Zenebo (Thomas Enebo)tom.enebo@gmail.com
<ul></ul><p>Ok cool. Let's hope we get some more consensus on this. I don't like deviating from MRI in behavior so I hope to see more come to the same conclusion.</p> Ruby master - Bug #16181: return from a proc in a module/class body returns out of script. Should be LJE.https://redmine.ruby-lang.org/issues/16181?journal_id=817992019-09-30T23:13:08Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>I've added a pull request that makes <code>return</code> in <code>proc</code> in <code>class</code>/<code>module</code> a <code>LocalJumpError</code>: <a href="https://github.com/ruby/ruby/pull/2511" class="external">https://github.com/ruby/ruby/pull/2511</a></p> Ruby master - Bug #16181: return from a proc in a module/class body returns out of script. Should be LJE.https://redmine.ruby-lang.org/issues/16181?journal_id=818092019-10-01T15:03:24Zenebo (Thomas Enebo)tom.enebo@gmail.com
<ul></ul><p>I added a comment about removing the pre 2.7 spec as it is unintended behavior.</p> Ruby master - Bug #16181: return from a proc in a module/class body returns out of script. Should be LJE.https://redmine.ruby-lang.org/issues/16181?journal_id=818312019-10-02T15:14:17Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>Fixed by <a class="changeset" title="Treat return in block in class/module as LocalJumpError (#2511) return directly in class/module ..." href="https://redmine.ruby-lang.org/projects/ruby-master/repository/git/revisions/ef697388becedf36966a2edcdcf88baca342b9e2">ef697388becedf36966a2edcdcf88baca342b9e2</a>.</p>