
Issue #20235 has been updated by mame (Yusuke Endoh). Currently, `!` and `?` are interpreted as a part of the method name unless they are followed by `=`. This trick is needed to interpret `foo!=bar` as `foo != bar`, not a method name `foo!`. I think this trick is not needed very much for `?`, so we may relax the condition to allow `?` followed by `=` as a method name. The following patch will solve the original issue. ```diff diff --git a/parse.y b/parse.y index 6836576d80..4db724a289 100644 --- a/parse.y +++ b/parse.y @@ -10657,7 +10657,7 @@ parse_ident(struct parser_params *p, int c, int cmd_state) if (tokadd_mbchar(p, c) == -1) return 0; c = nextc(p); } while (parser_is_identchar(p)); - if ((c == '!' || c == '?') && !peek(p, '=')) { + if ((c == '!' && !peek(p, '=')) || c == '?') { result = tFID; tokadd(p, c); } ``` However, note that the following code would still violate the OP's expectation. ```ruby p $stdin.raw!=>true ``` ---------------------------------------- Feature #20235: Deprecate CHAR syntax https://bugs.ruby-lang.org/issues/20235#change-106606 * Author: Dan0042 (Daniel DeLorme) * Status: Open * Priority: Normal ---------------------------------------- I propose deprecating the `?c` syntax. It served a purpose in ruby <= 1.8, but no longer. The reason I'm proposing this is because today I ran into this error: ```ruby p $stdin.closed?=>true # comparison of String with true failed (ArgumentError) ``` I was completed mystified, and had to resort to Ripper to figure out what's going on ``` p *Ripper.lex("p $stdin.closed?=>true") [[1, 0], :on_ident, "p", CMDARG] [[1, 1], :on_sp, " ", CMDARG] [[1, 2], :on_gvar, "$stdin", END] [[1, 8], :on_period, ".", DOT] [[1, 9], :on_ident, "closed", ARG] [[1, 15], :on_CHAR, "?=", END] #OOOOHH!!!!! [[1, 17], :on_op, ">", BEG] [[1, 18], :on_kw, "true", END] ``` We don't have to commit to a removal schedule right now, but I think it would at least be good to print a deprecation message if $VERBOSE. -- https://bugs.ruby-lang.org/