Bug #16498
Updated by ptsengineer (Peter Tsengineer) over 4 years ago
The most minimal reproduction I found, in Ruby 2.7:
```
$ ruby -e "puts Hash.new { }.transform_values { }.default"
#<Proc:0x000055eecda01510 -e:1>
```
That was unexpected for me, because 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 get 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"
```
```
$ ruby hash_default.rb
Traceback (most recent call last):
1: from hash_default.rb:7:in `<main>'
hash_default.rb:1:in `block in <main>': undefined method `[]=' for 0:Integer (NoMethodError)
Did you mean? []
```
That was quite a confusing error message, since it took a while to realise why `[]=` has gotten 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:
```
Traceback (most recent call last):
1: from hash_default.rb:7:in `<main>'
hash_default.rb:7:in `dig': Proc does not have #dig method (TypeError)
```