Feature #20331
closedShould parser warn hash duplication and when clause?
Description
Background¶
Right now, parser warns duplicated hash keys (#1) and when clause (#2).
For example,
{1 => :a, 1 => :b}
# => warning: key 1 is duplicated and overwritten on line 1
case 2
when 1, 1
else
end
# => test.rb:2: warning: duplicated `when' clause with line 2 is ignored
The parser compares different cardinality numbers.
{
1 => :a,
0x1 => :b,
0b1 => :b,
0d1 => :b,
0o1 => :b,
}
# => test.rb:2: warning: key 1 is duplicated and overwritten on line 3
# => test.rb:3: warning: key 1 is duplicated and overwritten on line 4
# => test.rb:4: warning: key 1 is duplicated and overwritten on line 5
# => test.rb:5: warning: key 1 is duplicated and overwritten on line 6
Problem¶
Currently this is implemeted by converting string like "123"
to Ruby Object and compare them.
It's needed to remove Ruby Object from parse.y for Universal Parser.
I created PR https://github.com/ruby/ruby/pull/10079 which implements bignum for parse.y without dependency on Ruby Object, however nobu and mame express concern about the cost and benefit of implmenting bignum for parser.
I want to discuss which is the best approach for this problem.
By the way, it's needed to calculate irreducible fraction for Rational key if we will keep warning messages.
$ ruby -wc -e '{10.2r => :a, 10.2r => :b}'
-e:1: warning: key (51/5) is duplicated and overwritten on line 1
-e:1: warning: unused literal ignored
Syntax OK
Options¶
1. Warnings on parser¶
Pros:
- Users of Universal Parser don't need to implement warnings by themselves. I guess developers of other Ruby implementation may get benefit of reducing their effort.
- Warnings are shown by
ruby -wc
.
Cons:
- We need to maintain bignum implementation for parser.
There are two approaches for this option.
1-1. Implement bignum for parser¶
The PR is this approach, implementing sub set of Ruby bignum for parser.
1-2. Extract existing bignum implementation then use it¶
Make existing bignum implementation to be independent of Ruby Object and use it from both bignum.c and parse.y.
2. Moving warnings logic into compile phase¶
We can use Ruby Object in compile.c. Then moving the logic into compile.c solves this problem.
Pros:
- No need to implement bignum for parser.
Cons:
- Users of Universal Parser need to implement warnings by themselves.
- Warnings are not shown by
ruby -wc
.