From: merch-redmine@... Date: 2020-05-23T02:26:04+00:00 Subject: [ruby-core:98487] [Ruby master Bug#16908] Strange behaviour of Hash#shift when used with `default_proc`. Issue #16908 has been updated by jeremyevans0 (Jeremy Evans). While your particular example is non-intuitive, there is a simple explanation for it. The first time `hash.shift` is called, `hash` is empty, so it returns the default value (`0`). It gets the default value by calling the default_proc for `hash` with a `nil` key. There is no better option since `hash.shift` isn't provided a key. The second time `hash.shift` is called, the hash is not empty, so it returns the first entry as a key value pair. I agree `Hash#shift` semantics with a default_proc are questionable, but I'm not sure if it could be improved. I don't think we should change this behavior. It is expected that `Hash.new.shift` should return nil, as should `Hash.new(nil).shift` and `Hash.new{}.shift`. `hash.shift` is used in conditionals: ```ruby hash = {a: 1, b: 2} while (k,v = hash.shift) p [k, v] end ``` If you change `Hash#shift` to return an array when the hash is empty, you've turned this into an infinite loop. ---------------------------------------- Bug #16908: Strange behaviour of Hash#shift when used with `default_proc`. https://bugs.ruby-lang.org/issues/16908#change-85763 * Author: ioquatix (Samuel Williams) * Status: Open * Priority: Normal * ruby -v: 2.7.0 * Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN ---------------------------------------- I don't have any strong opinion about this, but I observed the following behaviour which I thought was confusing. Maybe it's okay, or maybe we should change it to be more consistent. ``` hash = Hash.new{|k,v| k[v] = 0} hash.shift # => 0 hash.shift # => [nil, 0] ``` My feeling was, both cases should return `[nil, 0]`. -- https://bugs.ruby-lang.org/ Unsubscribe: