Which value for a duplicate key is ignored in a Ru

2019-07-11 03:08发布

问题:

If a hash has more than one occurrences of identical keys pointing to different values, then how does Ruby determine which value is assigned to that key?

In other words,

hash = {keyone: 'value1', keytwo: 'value2', keyone: 'value3'}

results in

warning: duplicated key at line 1 ignored: :keyone

but how do I know which value is assigned to :keyone?

回答1:

The last one overwrites the previous values. In this case, "value3" becomes the value for :keyone. This works just as the same with merge. When you merge two hashes that have the same keys, the value in the latter hash (not the receiver but the argument) overwrites the other value.



回答2:

Line numbers on duplicate key warnings can be misleading. As the other answers here confirm, every value of a duplicated key is ignored except for the last value defined for that key.

Using the example in the question across multiple lines:

1 hash1 = {key1: 'value1',
2 key2: 'value2', 
3 key1: 'value3'}
4 puts hash1.to_s

keydup.rb:1: warning: duplicated key at line 3 ignored: :key1
{:key1=>"value3", :key2=>"value2"}

The message says "line 3 ignored" but, in fact it was the value of the key defined at line 1 that is ignored, and the value at line 3 is used, because that is the last value passed into that key.



回答3:

IRB is your friend. Try the following in the command line:

irb
hash = {keyone: 'value1', keytwo: 'value2', keyone: 'value3'}
hash[:keyone]

What did you get? Should be "value3".

Best way to check these things is simply to try it out. It's one of the great things about Ruby.



回答4:

This is spelled out clearly in section 11.5.5.2 Hash constructor of the ISO Ruby Language Specification:

11.5.5.2 Hash constructor

Semantics

[...]

b) 2) For each association Ai, in the order it appears in the program text, take the following steps:

i) Evaluate the operator-expression of the association-key of Ai. Let Ki be the resulting value.

ii) Evaluate the operator-expression of the association-value. Let Vi be the resulting value.

iii) Store a pair of Ki and Vi in H by invoking the method []= on H with Ki and Vi as the arguments.