deffoo(bar=->{bar})end# no lambda parametersdeffoo(bar=->(){bar})end# no lambda parametersdeffoo(bar=baz{bar})end# no block parametersdeffoo(bar=baz{_1+bar})end# parameters, but no pipesdeffoo(bar=baz{it+bar})end# parameters, but no pipes
These cases are not syntax errors:
deffoo(bar=->(baz){bar})end# lambda parametersdeffoo(bar=baz{||bar})end# no block parameters but empty pipesdeffoo(bar=baz{|qux|bar})end# block parameters
I don't think these rules are very intuitive, and they feel somewhat arbitrary. I would like to suggest we change them to be either:
Syntax error is raised if the parameter is ever read in its default value at any scope depth
Syntax error is raised if the parameter is ever read in its default value at depth 0
Either one is fine by me, but gating the syntax error based on the presence of pipes is really confusing.
@nobu (Nobuyoshi Nakada) another option would be to delete those tests and leave it up to the parser instead of forcing parse.y to implement it. Specifically I'm talking about:
o = Object.new
assert_warn("") do
o.instance_eval("def foo(var: bar {| | var}) var end")
end
o = Object.new
assert_warn("") do
o.instance_eval("def foo(var: bar {|| var}) var end")
end
and
o = Object.new
assert_warn("") do
o.instance_eval("def foo(var = bar {| | var}) var end")
end
o = Object.new
assert_warn("") do
o.instance_eval("def foo(var = bar {|| var}) var end")
end
If it's too complicated to implement in parse.y, then removing these tests would be a good compromise. These tests themselves are the issue blocking me.
If we go with only syntax errors at depth 0, then this:
deffoo(bar=baz{bar})end
should not be a syntax error either. I think that makes sense, because the baz method could use instance_exec/instance_eval so we don't know if bar is going to be the same variable here or not.
Discussed at the dev meeting. @matz (Yukihiro Matsumoto) said all cases should be accepted with no syntax error. So def foo(bar = bar) = bar; foo will return nil with no warning and error.