Bug #20675
closed
Parse error with required kwargs and omitted parens
Added by matz (Yukihiro Matsumoto) 3 months ago.
Updated 2 months ago.
Description
As pointed out in https://github.com/mruby/mruby/issues/6268, keyword arguments without surrounding parens are a bit confusing, e.g.
def foo arg:
123
end
is parsed as
def foo(arg:)
123
end
where
k=25
f k:
10
is parserd as
k=25
f(k: 10)
In summary, should we ignore newlines after keyword labels? Should we make them behave consistent?
Matz.
I think this would be great and would love to use keyword parameters without parenthesis...but I don't know how complicated this would be for the parser (including backwards compatibility which Jeremy (Evans) has mentioned before). If this were made possible -- there is an upside -- as anonymous blocks would also benefit from this support as this is not valid syntax (currently):
def demo positional, &block
other positional, &block
end
💡 For more on this, see Issue 18441.
I agree that f k:
at end of line should be parsed as f(k:)
. Even though it is backward incompatible, it can be detected statically, so the migration path is easy. Ruby 3.4 could output a deprecation warning at parse time. We could have a script/gem to detect if the pattern is currently used in any files, so people can check their application code. If it's used in any gems they could be flagged as incompatible with Ruby 3.5. There's a number of pain-free ways of dealing with this.
I believe Matz was talking about changing the behavior of f k:<newline>
, so method definition def foo k:<newline>
would remain the same.
Although f k:<newline>expr
would be incompatible, what about f(k:<newline>expr)
?
The reason for this inconsistency is backwards compatibility, so as not to break existing code when omitted hash value support was added in Ruby 3.1.
There is historical precedence for breaking backwards compatibility for a very similar case. In this example:
def foo arg:
123
arg
end
foo
# Ruby < 2.0: SyntaxError
# Ruby 2.0: 123
# Ruby >= 2.1: ArgumentError, missing keyword: arg
There was no deprecation warning for the change in 2.1. I think if we want to change behavior for foo arg:<newline>value
from foo(arg: value)
to foo(arg:); value
, we should add a deprecation warning in 3.4, and then change the behavior in 3.5.
Dan0042 (Daniel DeLorme) wrote in #note-4:
I believe Matz was talking about changing the behavior of f k:<newline>
, so method definition def foo k:<newline>
would remain the same.
Although f k:<newline>expr
would be incompatible, what about f(k:<newline>expr)
?
for f k:<newline>val
, I found about 500 cases.
https://gist.github.com/ko1/e15fd4959675db07188e7a67ddc1c2c6
for f k:<newline>val
, I found about 500 cases.
Thank you for searching. That's a lot more than I was able to find in my 950 sample gems, and with such a number I would vote to not change anything.
- Status changed from Open to Closed
OK, I understand the reason and background of this behavior. The issue is withdrawn.
Matz.
Also available in: Atom
PDF
Like1
Like0Like1Like0Like0Like1Like0Like0Like0