https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112014-11-01T02:37:46ZRuby Issue Tracking SystemRuby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=497602014-11-01T02:37:46Zsilverhammermba (Max Anselm)silverhammermba+ruby@gmail.com
<ul></ul><p>That's because bash is trying to interpolate the string.</p>
<pre><code>$ ruby -e 'p :!@'
:!
</code></pre> Ruby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=792292019-07-09T03:58:04Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>I did some research, and this is related to the fact that Ruby allows <code>!@</code> and <code>~@</code> as method names (back to the initial SVN revision for <code>~@</code>), silently dropping the <code>@</code> from the method name:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span>
<span class="k">def</span> <span class="o">!</span><span class="err">@</span><span class="p">;</span> <span class="p">:</span><span class="o">!</span><span class="err">@</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">~</span><span class="err">@</span><span class="p">;</span> <span class="ss">:~</span><span class="err">@</span> <span class="k">end</span>
<span class="k">end</span>
<span class="o">!</span><span class="no">A</span><span class="p">.</span><span class="nf">new</span>
<span class="c1"># :!</span>
<span class="o">~</span><span class="no">A</span><span class="p">.</span><span class="nf">new</span>
<span class="c1"># :~</span>
<span class="no">A</span><span class="p">.</span><span class="nf">instance_methods</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span>
<span class="c1"># => [:!, :~]</span>
</code></pre>
<p>This diff would remove this behavior:</p>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/parse.y b/parse.y
index 33f1ef072e..ed7dae8955 100644
</span><span class="gd">--- a/parse.y
</span><span class="gi">+++ b/parse.y
</span><span class="p">@@ -8772,6 +8772,7 @@</span> parser_yylex(struct parser_params *p)
if (IS_AFTER_OPERATOR()) {
SET_LEX_STATE(EXPR_ARG);
if (c == '@') {
<span class="gi">+ pushback(p, c);
</span> return '!';
}
}
<span class="p">@@ -9184,9 +9185,6 @@</span> parser_yylex(struct parser_params *p)
case '~':
if (IS_AFTER_OPERATOR()) {
<span class="gd">- if ((c = nextc(p)) != '@') {
- pushback(p, c);
- }
</span> SET_LEX_STATE(EXPR_ARG);
}
else {
</code></pre>
<p>However, it breaks using <code>~@</code> and <code>!@</code> as method names, which is breaks one test in bootstraptest. This is because both the symbol and the method name use <code>fname</code> in the parser. There is probably a way to remove support for using these in symbols but keeping the support in method names that I am not currently aware of. However, I'm sure if we want to keep supporting <code>~@</code> and <code>!@</code> in method names.</p>
<p>FWIW, JRuby handles <code>:~@</code> and <code>:!@</code> the same way as CRuby.</p> Ruby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=792482019-07-09T15:30:13Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>If <code>:!@</code> and <code>:!</code> are different things, also <code>!foo</code> and <code>foo.!</code> are different things.<br>
This means a backward incompatibility.</p> Ruby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=792502019-07-09T15:56:51Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>nobu (Nobuyoshi Nakada) wrote:</p>
<blockquote>
<p>If <code>:!@</code> and <code>:!</code> are different things, also <code>!foo</code> and <code>foo.!</code> are different things.</p>
</blockquote>
<p>I don't believe that is true. With the above patch:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span>
<span class="k">def</span> <span class="o">!</span><span class="p">;</span> <span class="p">:</span><span class="o">!</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">~</span><span class="p">;</span> <span class="ss">:~</span> <span class="k">end</span>
<span class="k">end</span>
<span class="o">!</span><span class="no">A</span><span class="p">.</span><span class="nf">new</span>
<span class="c1"># :!</span>
<span class="no">A</span><span class="p">.</span><span class="nf">new</span><span class="o">.!</span>
<span class="c1"># :!</span>
<span class="o">~</span><span class="no">A</span><span class="p">.</span><span class="nf">new</span>
<span class="c1"># :~</span>
<span class="no">A</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">~</span>
<span class="c1"># :~</span>
</code></pre>
<p>The <code>@</code> in <code>:!@</code> and <code>def !@; end</code> was ignored during lexing before, it doesn't affect the semantics. This is different than <code>+@</code> and <code>+</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span>
<span class="k">def</span> <span class="nf">+</span><span class="p">;</span> <span class="p">:</span><span class="o">+</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">+@</span><span class="p">;</span> <span class="ss">:+@</span> <span class="k">end</span>
<span class="k">end</span>
<span class="o">+</span><span class="no">A</span><span class="p">.</span><span class="nf">new</span>
<span class="c1"># :+@</span>
<span class="no">A</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">+</span>
<span class="c1"># :+</span>
</code></pre>
<blockquote>
<p>This means a backward incompatibility.</p>
</blockquote>
<p>The backward incompatibility should be limited to making the following invalid syntax:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="o">!</span><span class="err">@</span><span class="p">;</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">~</span><span class="err">@</span><span class="p">;</span> <span class="k">end</span>
<span class="k">alias</span> <span class="n">foo</span> <span class="o">!</span><span class="err">@</span>
<span class="k">alias</span> <span class="n">bar</span> <span class="o">~</span><span class="err">@</span>
<span class="p">:</span><span class="o">!</span><span class="err">@</span>
<span class="ss">:~</span><span class="err">@</span>
</code></pre>
<p>Currently, <code>:!@</code> is different than <code>:"!@"</code>, which very much appears to be a bug. With the above patch <code>:!@</code> is a syntax error (<code>:"!@"</code> is still valid).</p> Ruby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=792512019-07-09T16:40:48Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul></ul><p>jeremyevans0 (Jeremy Evans) wrote:</p>
<blockquote>
<p>nobu (Nobuyoshi Nakada) wrote:</p>
<blockquote>
<p>If <code>:!@</code> and <code>:!</code> are different things, also <code>!foo</code> and <code>foo.!</code> are different things.</p>
</blockquote>
<p>I don't believe that is true. With the above patch:</p>
</blockquote>
<p>Sorry, forgot <code>@</code>, I wanted to mean <code>!foo</code> and <code>foo.!@</code>.</p> Ruby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=792522019-07-09T16:53:55Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul></ul><p>nobu (Nobuyoshi Nakada) wrote:</p>
<blockquote>
<p>jeremyevans0 (Jeremy Evans) wrote:</p>
<blockquote>
<p>nobu (Nobuyoshi Nakada) wrote:</p>
<blockquote>
<p>If <code>:!@</code> and <code>:!</code> are different things, also <code>!foo</code> and <code>foo.!</code> are different things.</p>
</blockquote>
<p>I don't believe that is true. With the above patch:</p>
</blockquote>
<p>Sorry, forgot <code>@</code>, I wanted to mean <code>!foo</code> and <code>foo.!@</code>.</p>
</blockquote>
<p>Well, <code>foo.!@</code> would be a syntax error with the patch. Is there a reason other than backwards compatibility to keep this automatic aliasing of <code>!@</code> to <code>!</code> and <code>~@</code> to <code>~</code>? If not, maybe we could deprecate this in 2.7 and remove it in Ruby 3 (if matz approves).</p> Ruby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=792642019-07-10T09:27:12Zshevegen (Robert A. Heiler)shevegen@gmail.com
<ul></ul><p>Interesting - I did not know this. sawa finds stuff. :)</p>
<p>Personally I would be in favour of changing the behaviour as Jeremy described (I also think this<br>
may be a bug or perhaps an oddity), but I guess it depends on a) whether matz wants to change it<br>
in the first place and b) then when to change it, if a) evaluates to a change.</p>
<p>A secondary consideration may be to query how many ruby users depend on this backwards behaviour.</p>
<p>I have no statistical dataset to make a statement either way, but from intuition, I would venture<br>
that this change would not affect a lot of ruby code out there; I could be wrong though.</p> Ruby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=797062019-07-18T19:22:05Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>File</strong> <a href="/attachments/7907">tilde-bang-at-symbols.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/7907/tilde-bang-at-symbols.patch">tilde-bang-at-symbols.patch</a> added</li></ul><p>matz confirmed in the last developer meeting that he wants <code>def !@; end</code> to continue to work. However, I still think we should fix it so that <code>:!@</code> and <code>:~@</code> are not treated as <code>:!</code> and <code>:~</code>. This is a bit tricky to do as the parser currently uses the same lex state for both cases (<code>EXPR_FNAME</code>).</p>
<p>The simplest way I can think to fix this is in the attached patch. It changes the <code>:!</code> and <code>:~</code> cases to use lex state <code>EXPR_FNAME|EXPR_FITEM</code>, and changes the code to check on whether <code>EXPR_FITEM</code> is one of the lex states. If <code>EXPR_FITEM</code> is one of the lex states, then it doesn't ignore the <code>@</code>.</p> Ruby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=802562019-07-30T07:40:00Zko1 (Koichi Sasada)
<ul><li><strong>Assignee</strong> set to <i>nobu (Nobuyoshi Nakada)</i></li></ul> Ruby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=813472019-09-02T06:30:56Zko1 (Koichi Sasada)
<ul><li><strong>Tracker</strong> changed from <i>Bug</i> to <i>Feature</i></li><li><strong>Assignee</strong> changed from <i>nobu (Nobuyoshi Nakada)</i> to <i>matz (Yukihiro Matsumoto)</i></li><li><strong>ruby -v</strong> deleted (<del><i>2.1.4</i></del>)</li><li><strong>Backport</strong> deleted (<del><i>2.0.0: UNKNOWN, 2.1: UNKNOWN</i></del>)</li></ul> Ruby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=832872019-12-20T08:12:34Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Rejected</i></li></ul><p>I don't see the practical benefit of this proposal. Besides that incompatibility is a clear drawback.</p>
<p>Matz.</p> Ruby master - Feature #10463: :~@ and :!@ are not parsed correctlyhttps://redmine.ruby-lang.org/issues/10463?journal_id=940652021-10-07T18:04:40Zjeremyevans0 (Jeremy Evans)merch-redmine@jeremyevans.net
<ul><li><strong>Has duplicate</strong> <i><a class="issue tracker-1 status-5 priority-4 priority-default closed" href="/issues/18246">Bug #18246</a>: send does not work for unary ! operator when operator isn't a literal symbol</i> added</li></ul>