https://redmine.ruby-lang.org/
https://redmine.ruby-lang.org/favicon.ico?1711330511
2018-12-12T13:09:31Z
Ruby Issue Tracking System
Ruby master - Bug #15404: Endless range has inconsistent chaining behaviour
https://redmine.ruby-lang.org/issues/15404?journal_id=75607
2018-12-12T13:09:31Z
valich (Valentin Fondaratov)
<ul><li><strong>ruby -v</strong> changed from <i>2.6.0-rc1</i> to <i>ruby 2.6.0rc1 (2018-12-06 trunk 66253) [x86_64-linux]</i></li></ul>
Ruby master - Bug #15404: Endless range has inconsistent chaining behaviour
https://redmine.ruby-lang.org/issues/15404?journal_id=75610
2018-12-12T15:44:05Z
mame (Yusuke Endoh)
mame@ruby-lang.org
<ul></ul><p>Thank you for your report.</p>
<p>valich (Valentin Fondaratov) wrote:</p>
<blockquote>
<a name="Why-its-important"></a>
<h2 >Why it's important<a href="#Why-its-important" class="wiki-anchor">¶</a></h2>
<p>All the code above will break on runtime because it leads to <code>bad value for range (ArgumentError)</code>. However, if the code is located in some method (or branch) which is executed rarely, developer might miss the problem.</p>
</blockquote>
<p>I understand the problem. But, it is not specific to endless range, is it? In fact, <code>(1..1)..1</code> does parse, and fails to run.</p>
<p>It is possible to prohibit all nested ranges, including a non-endless range <code>(1..1)..1</code> and an endless range <code>(1..)..1</code>. This brings very small incompatibility which is acceptable IMO.</p>
<p>Nobu's patch:</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git i/parse.y w/parse.y
index 278c5b0296..1c76af541a 100644
</span><span class="gd">--- i/parse.y
</span><span class="gi">+++ w/parse.y
</span><span class="p">@@ -380,6 +380,8 @@</span> static void void_expr(struct parser_params*,NODE*);
static NODE *remove_begin(NODE*);
static NODE *remove_begin_all(NODE*);
#define value_expr(node) value_expr_gen(p, (node) = remove_begin(node))
<span class="gi">+static int range_expr_gen(struct parser_params*,NODE*);
+#define range_expr(node) range_expr_gen(p, (node) = remove_begin(node))
</span> static NODE *void_stmts(struct parser_params*,NODE*);
static void reduce_nodes(struct parser_params*,NODE**);
static void block_dup_check(struct parser_params*,NODE*,NODE*);
<span class="p">@@ -1909,8 +1911,8 @@</span> arg : lhs '=' arg_rhs
| arg tDOT2 arg
{
/*%%%*/
<span class="gd">- value_expr($1);
- value_expr($3);
</span><span class="gi">+ range_expr($1);
+ range_expr($3);
</span> $$ = NEW_DOT2($1, $3, &@$);
/*% %*/
/*% ripper: dot2!($1, $3) %*/
<span class="p">@@ -1918,8 +1920,8 @@</span> arg : lhs '=' arg_rhs
| arg tDOT3 arg
{
/*%%%*/
<span class="gd">- value_expr($1);
- value_expr($3);
</span><span class="gi">+ range_expr($1);
+ range_expr($3);
</span> $$ = NEW_DOT3($1, $3, &@$);
/*% %*/
/*% ripper: dot3!($1, $3) %*/
<span class="p">@@ -1931,7 +1933,7 @@</span> arg : lhs '=' arg_rhs
loc.beg_pos = @2.end_pos;
loc.end_pos = @2.end_pos;
<span class="gd">- value_expr($1);
</span><span class="gi">+ range_expr($1);
</span> $$ = NEW_DOT2($1, new_nil(&loc), &@$);
/*% %*/
/*% ripper: dot2!($1, Qnil) %*/
<span class="p">@@ -1943,7 +1945,7 @@</span> arg : lhs '=' arg_rhs
loc.beg_pos = @2.end_pos;
loc.end_pos = @2.end_pos;
<span class="gd">- value_expr($1);
</span><span class="gi">+ range_expr($1);
</span> $$ = NEW_DOT3($1, new_nil(&loc), &@$);
/*% %*/
/*% ripper: dot3!($1, Qnil) %*/
<span class="p">@@ -9540,6 +9542,18 @@</span> value_expr_gen(struct parser_params *p, NODE *node)
return TRUE;
}
<span class="gi">+static int
+range_expr_gen(struct parser_params *p, NODE *node)
+{
+ switch (nd_type(node)) {
+ case NODE_DOT2:
+ case NODE_DOT3:
+ yyerror1(&node->nd_loc, "nested range");
+ return FALSE;
+ }
+ return value_expr_gen(p, node);
+}
+
</span> static void
void_expr(struct parser_params *p, NODE *node)
{
</code></pre>
<p><a class="user active user-mention" href="https://redmine.ruby-lang.org/users/13">@matz (Yukihiro Matsumoto)</a> and <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/5">@naruse (Yui NARUSE)</a>, can we commit it? Is it okay to reject <code>(1..1)..1</code> as a parse error?</p>
Ruby master - Bug #15404: Endless range has inconsistent chaining behaviour
https://redmine.ruby-lang.org/issues/15404?journal_id=76597
2019-01-30T21:54:26Z
kddnewton (Kevin Newton)
kddnewton@gmail.com
<ul></ul><p>Just want to add to this that</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Ripper</span><span class="p">.</span><span class="nf">sexp</span><span class="p">(</span><span class="s2">"1..</span><span class="se">\n</span><span class="s2">1..5"</span><span class="p">)</span>
</code></pre>
<p>breaks and returns nil</p>
Ruby master - Bug #15404: Endless range has inconsistent chaining behaviour
https://redmine.ruby-lang.org/issues/15404?journal_id=93201
2021-08-09T19:40:32Z
jeremyevans0 (Jeremy Evans)
merch-redmine@jeremyevans.net
<ul></ul><p>I don't think we should make a range of literal ranges a parse error. While a range of ranges is not useful by default, a developer could define <code>Range#<=></code> and <code>Range#succ</code> such that a range of ranges could be useful:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Range</span>
<span class="k">def</span> <span class="nf"><</span><span class="o">=></span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="p">[</span><span class="nb">self</span><span class="p">.</span><span class="nf">begin</span><span class="p">,</span> <span class="nb">self</span><span class="p">.</span><span class="nf">end</span><span class="p">]</span> <span class="o"><=></span> <span class="p">[</span><span class="n">other</span><span class="p">.</span><span class="nf">begin</span><span class="p">,</span> <span class="n">other</span><span class="p">.</span><span class="nf">end</span><span class="p">]</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">succ</span>
<span class="p">(</span><span class="nb">self</span><span class="p">.</span><span class="nf">begin</span><span class="p">.</span><span class="nf">succ</span><span class="p">)</span><span class="o">..</span><span class="p">(</span><span class="nb">self</span><span class="p">.</span><span class="nf">end</span><span class="p">.</span><span class="nf">succ</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>Therefore, making a range of literal ranges a parse error seems wrong to me.</p>
Ruby master - Bug #15404: Endless range has inconsistent chaining behaviour
https://redmine.ruby-lang.org/issues/15404?journal_id=93395
2021-08-19T07:18:03Z
matz (Yukihiro Matsumoto)
matz@ruby.or.jp
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Rejected</i></li></ul><p>I think it's OK to keep the current behavior. <code>1.. ..2</code> looks weird, I agree, but don't need to be a syntax error.</p>
<p>Matz.</p>