It's possible https://github.com/yui-knk/ruby/tree/bugs_17925.
I think this is not limitaion but the matter of choice. Currently expr
is expected after case
therefore expression in 42
is interpreted as expr
.
For example
case expression in 42
in true
in false
end
Before the change, this is interpreted as
case (expression in 42)
in true
in false
end
After the change, this is interpreted as
case expression
in 42
in true
in false
end
Impact¶
For case ... in
As shown above, this will change the behavior of current codes.
Before:
expression = 42
case expression in 42
in true
p :t
in false
p :f
end
#=> :t
expression = 421
case expression in 42
in true
p :t
in false
p :f
end
#=> :f
After:
expression = 42
case expression in 42
in true
p :t
in false
p :f
end
#=> nothing printed, because body for 42 is empty
expression = 421
case expression in 42
in true
p :t
in false
p :f
end
#=> 421 (NoMatchingPatternError)
# because nothing matches
For case ... when
Before this change, this is valid
case expression in 42
when true
p :t
when false
p :f
end
However after this change, it's invalid
case expression in 42
when true
p :t
when false
p :f
end
# test2.rb:2: syntax error, unexpected `when' (SyntaxError)
# when true
# ^~~~
Impact on case ... when
is inevitable because new grammar recognizes this is case ... in
when third symbol (in
) appears.
New exception¶
expr
appears other place of the grammar. For example, if expr ...
, while expr ...
and so on. This change introduces an exception that you can write one line pattern matching after if
, unless
, while
, until
and so on but you can't after case
.
Conclusion¶
- This a matter of choice not limitaion
- New grammar introduces incompatibility. It changes the behavior of
case ... in
and breaks case ... when
- It introduces an exceptional rule to the grammar
- As a reporter says, there is workaround to add
;
after expression
expression in 42
always returns true
or false
therefore it might be useless for case
. Howerver we need to consider such impacts and benefits before decision making.
Note¶
Impact on case ... when
can be found as Shift/Reduce conflict. In this state, shift derives case ... when
, on the other hand reduce derives case ... in
.
https://github.com/yui-knk/ruby/tree/bugs_17925_2
State 394
shift/reduce conflict on token "`in'":
60 expr0: arg •
71 expr: arg • "`in'" @7 @8 p_top_expr_body
First example: $@1 k_case arg • "`in'" @7 @8 p_top_expr_body opt_terms @19 case_body k_end "=>" @5 @6 p_top_expr_body opt_terms
Shift derivation
program
↳ 2: $@1 top_compstmt
↳ 3: top_stmts opt_terms
↳ 5: top_stmt
↳ 7: stmt
↳ 37: expr
↳ 68: arg "=>" @5 @6 p_top_expr_body
↳ 269: primary
↳ 358: k_case expr_value opt_terms @19 case_body k_end
↳ 78: expr
↳ 71: arg • "`in'" @7 @8 p_top_expr_body
Second example: $@1 k_case arg • opt_terms "`in'" @38 @39 p_top_expr then $@40 compstmt p_cases k_end '[' opt_call_args rbracket "operator-assignment" lex_ctxt command_rhs opt_terms "end-of-input"
Reduce derivation
$accept
↳ 0: program "end-of-input"
↳ 2: $@1 top_compstmt
↳ 3: top_stmts opt_terms
↳ 5: top_stmt
↳ 7: stmt
↳ 32: command_asgn
↳ 41: primary_value '[' opt_call_args rbracket "operator-assignment" lex_ctxt command_rhs
↳ 377: primary
↳ 361: k_case expr_value0 opt_terms p_case_body k_end
↳ 77: expr0 ↳ 500: "`in'" @38 @39 p_top_expr then $@40 compstmt p_cases
↳ 60: arg •