Actions
Bug #16498
closedHash#transform_values in 2.7.0 sets new hash's default to old hash's default_proc
Bug #16498: Hash#transform_values in 2.7.0 sets new hash's default to old hash's default_proc
Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux]
Description
The following is unexpected for me.
Hash.new { }.transform_values { }.default # => #<Proc:0x000055eecda01510 -e:1> Hash.new { }.transform_values { }[:any] # => #<Proc:0x0000563a12e35510 -e:1> Hash.new { :default }.transform_values { }[:any][] # => :default I did not think a default_proc would turn into a default. The previous behaviour in 2.6 was that the default would be nil, so this is new in 2.7. But I didn't see this mentioned in the 2.7 NEWS. May I learn of the proper use for this and/or whether it is intentional?
If you wonder when we might see something like this, I had found it with code similar in idea to the following:
weights = Hash.new { |h, k| h[k] = [] } weights[:apple] << 1 weights[:apple] << 2 prices = weights.transform_values { :arbitrary } puts (prices[:mango] || [])[0] || "We're all out of mangoes today" in `block in <main>': undefined method `[]=' for 0:Integer (NoMethodError) That was quite a confusing error message. It took a while to realise why []= was called on 0.
We also cannot fix this by using dig (puts prices.dig(:mango, 0) || "We're all out of mangoes today") because then, we would get:
in `dig': Proc does not have #dig method (TypeError) Actions