Bug #21994
openIf there is a local variable `foo`, calls to a method `foo` with a regexp literal as first argument is always a SyntaxError without parentheses
Description
Quick version:¶
ruby -e 'p /hello/' # => /hello/ (warning)
ruby -e 'p = 1; p /hello/' # syntax error
ruby -e 'p %r/hello/' # => /hello/ (no warning)
ruby -e 'p = 1; p %r/hello/' # syntax error
Context¶
In Rouge, our lexing DSL originally looked like this:
rule /some_regex/, Some::TokenType, :next_state
rule /some_other_regex/ do |match|
# custom action
end
In a DSL context like this, I feel that using parentheses for every rule definition is a hassle and looks bad, so we leave them off, as is convention.
Unfortunately, this warns:
warning: ambiguous `/`; wrap regexp in parentheses or add a space after `/` operator
Some time ago, to reduce warning-spam on users who run with -w, we transitioned all of these to use %r/.../ or %r(...) syntax, which does not warn.
The issue here I think is that both cases are equivalently ambiguous in some sense, which becomes apparent with the local-scope-dependent behaviour of the parser (putting aside that dependency on local variable scope makes the Ruby syntax highlighting of Rouge more or less impossible to do correctly without a full parse). If there is a local variable named rule introduced at any point, even several block scopes above, the entire file errors out in a very confusing manner.
At the very least, I feel that the warnings here are inconsistent. If both cases truly are ambiguous and dependent on local variable scope, perhaps it would be better to warn on both - though that would make using a regex literal as a first argument always require parentheses to avoid warnings, which would make my DSL much harder. I'm honestly not entirely sure what a good solution would be, but I would like to open a discussion on the topic. Perhaps philosophically related to the other bug I have open ( #21870 ) - is this truly worthy of a warning, or should this be a linter concern?