Project

General

Profile

Actions

Bug #19910

closed

Set#delete_if behavior inconsistent with Array/Hash

Bug #19910: Set#delete_if behavior inconsistent with Array/Hash

Added by segiddins (Samuel Giddins) almost 3 years ago. Updated 3 days ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:114943]

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:

[1, 3, 5, 6, 7]
{1=>1, 3=>3, 5=>5, 6=>6, 7=>7}
#<Set: {0, 1, 2, 3, 4, 5, 6, 7}>

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 Actions #1 [ruby-core:114946]

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 wanabe (_ wanabe) 3 days ago Actions #3 [ruby-core:126399]

  • 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}>
Actions

Also available in: PDF Atom