Bug #19910
closedSet#delete_if behavior inconsistent with Array/Hash
Description
Given the following script:
#!/usr/bin/env ruby
require 'set'
def enum(collection)
i = 0
collection.delete_if do
i += 1
raise ArgumentError if i == 6
i.odd?
end
rescue ArgumentError
return collection
end
pp enum([0, 1, 2, 3, 4, 5, 6, 7])
pp enum([0, 1, 2, 3, 4, 5, 6, 7].to_h { [_1, _1] })
pp enum([0, 1, 2, 3, 4, 5, 6, 7].to_set)
It results in:
As you can see, when an exception is raise inside delete_if on Hash/Array, the already-considered elements are still removed from the array. For Set, no elements are deleted (due to the implementation that builds up an intermediary list of elements to delete, then removes them from the underlying hash afterwards). It would be very helpful if Set#delete_if behaved consistently with other core collection types
Updated by stevegeek (Stephen Ierodiaconou) almost 3 years ago
I was just looking at this, and it seems like the behaviour used to be as you expected but changed in v2.1, https://github.com/ruby/ruby/commit/2849ee5d18360f26b55643a2643a1c597376865d
Updated by the_spectator (Akshay Birajdar) almost 3 years ago
Took a stab at it in https://github.com/ruby/ruby/pull/8642
Updated by wanabe (_ wanabe) 3 days ago
- Status changed from Open to Closed
This behavior was fixed by e4f85bfc311a3812de7bc2e9d068934e8b364574 == https://bugs.ruby-lang.org/issues/21216.
$ git checkout e4f85bfc311a3812de7bc2e9d068934e8b364574~ && make -j miniruby > /de
v/null && ./miniruby -I$(git rev-parse --show-toplevel)/lib a.rb
Previous HEAD position was e4f85bfc311 Implement Set as a core class
HEAD is now at b1283b45e62 maybe fix bindgen
[1, 3, 5, 6, 7]
{1 => 1, 3 => 3, 5 => 5, 6 => 6, 7 => 7}
#<Set: {0, 1, 2, 3, 4, 5, 6, 7}>
$ git checkout e4f85bfc311a3812de7bc2e9d068934e8b364574 && make -j miniruby > /dev
/null && ./miniruby -I$(git rev-parse --show-toplevel)/lib a.rb
Previous HEAD position was b1283b45e62 maybe fix bindgen
HEAD is now at e4f85bfc311 Implement Set as a core class
[1, 3, 5, 6, 7]
{1 => 1, 3 => 3, 5 => 5, 6 => 6, 7 => 7}
#<Set: {1, 3, 5, 6, 7}>