Bug #20482
closednil variables in a guard clause of a standalone => or in expression
Description
The following expression produces a TypeError, which is quite unexpected:
[1, 2] in a, b if b == 2*a
x.rb:1:in `*': nil can't be coerced into Integer (TypeError)
[1, 2] in a, b if b == 2*a
^
from x.rb:1:in `<main>'
The expression above should be equivalent to the following one, which works as expected:
case [1, 2]
in a, b if b == 2*a
true
else
false
end
# => true
Apologies in advance if this is intentional or has been reported before.
Updated by nobu (Nobuyoshi Nakada) 7 months ago
One-line pattern matching can not have a guard clause, so the if
in the first example is a modifier if
and is evaluated before the pattern matching.
In short, it should be intentional, I think.
Updated by Soilent (Konstantin x) 7 months ago
Thank you, nobu! That explains it.
Just to clarify, is this how the expression is parsed?
( [1, 2] in a, b ) if b == 2*a
And since this is a modifier if
, the parser creates variables a and b first, which is why they are defined in the test expression?
Updated by nobu (Nobuyoshi Nakada) 7 months ago
Soilent (Konstantin x) wrote in #note-2:
Thank you, nobu! That explains it.
Just to clarify, is this how the expression is parsed?
( [1, 2] in a, b ) if b == 2*a
Yes, you can confirm the AST by ruby --dump=parsetree -e '1 in a if a'
(the code is simplified).
And since this is a modifier
if
, the parser creates variables a and b first, which is why they are defined in the test expression?
Yes, a
and b
are created by [1, 2] in a, b
and available in the if
condition.
Updated by nobu (Nobuyoshi Nakada) 7 months ago
- Status changed from Open to Closed
Applied in changeset git|b911d2222f907d3fad397938e8f513ecfb4635b8.
[Bug #20482] [DOC] Clarify about pattern maching guard clause
Guard clauses can only be used in case
pattern matching statements,
not in =>
/in
operators.