[ruby-core:114943] [Ruby master Bug#19910] Set#delete_if behavior inconsistent with Array/Hash

Issue #19910 has been reported by segiddins (Samuel Giddins). ---------------------------------------- Bug #19910: Set#delete_if behavior inconsistent with Array/Hash https://bugs.ruby-lang.org/issues/19910 * Author: segiddins (Samuel Giddins) * Status: Open * Priority: Normal * ruby -v: 3.2.2 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Given the following script: ```ruby #!/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 -- https://bugs.ruby-lang.org/

😉 вт, 3 окт. 2023 г. в 03:05, segiddins (Samuel Giddins) via ruby-core < ruby-core@ml.ruby-lang.org>:
Issue #19910 has been reported by segiddins (Samuel Giddins).
---------------------------------------- Bug #19910: Set#delete_if behavior inconsistent with Array/Hash https://bugs.ruby-lang.org/issues/19910
* Author: segiddins (Samuel Giddins) * Status: Open * Priority: Normal * ruby -v: 3.2.2 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Given the following script:
```ruby #!/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
-- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org...

Issue #19910 has been updated by stevegeek (Stephen Ierodiaconou). 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 ---------------------------------------- Bug #19910: Set#delete_if behavior inconsistent with Array/Hash https://bugs.ruby-lang.org/issues/19910#change-104817 * Author: segiddins (Samuel Giddins) * Status: Open * Priority: Normal * ruby -v: 3.2.2 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Given the following script: ```ruby #!/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 -- https://bugs.ruby-lang.org/

Issue #19910 has been updated by the_spectator (Akshay Birajdar). Took a stab at it in https://github.com/ruby/ruby/pull/8642 ---------------------------------------- Bug #19910: Set#delete_if behavior inconsistent with Array/Hash https://bugs.ruby-lang.org/issues/19910#change-104908 * Author: segiddins (Samuel Giddins) * Status: Open * Priority: Normal * ruby -v: 3.2.2 * Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- Given the following script: ```ruby #!/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 -- https://bugs.ruby-lang.org/
participants (4)
-
segiddins (Samuel Giddins)
-
stevegeek (Stephen Ierodiaconou)
-
the_spectator (Akshay Birajdar)
-
Игорь Пятчиц