Issue #15830 has been updated by jeremyevans0 (Jeremy Evans).

Assignee set to knu (Akinori MUSHA)
Status changed from Open to Assigned
File sorted-set-initialize.patch added

I agree this is a bug and the easiest way to fix it is to inline the `SortedSet#initialize` implementation defined by `SortedSet.setup` into the default implementation of `SortedSet#initialize`.  Attached is a patch that implements that.

----------------------------------------
Bug #15830: SortedSet's lazy setup causes unpredictable behaviour in subclass's initialize
https://bugs.ruby-lang.org/issues/15830#change-78346

* Author: viko (Viko Viko)
* Status: Assigned
* Priority: Normal
* Assignee: knu (Akinori MUSHA)
* Target version: 
* ruby -v: ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]
* Backport: 2.4: UNKNOWN, 2.5: UNKNOWN, 2.6: UNKNOWN
----------------------------------------
``` ruby
require 'set'

class SortedSetWithoutLowest < SortedSet
  def initialize contents=[]
    puts "initialize, #{contents}"
    super
    lowest = to_a[0]
    puts "lowest from #{contents} is #{lowest}, removing"
    delete lowest
    puts "done initializing #{contents} to #{self}"
  end
end

3.times { SortedSetWithoutLowest[1,2,3,4,5] }
```

```
initialize, [1, 2, 3, 4, 5]
initialize, [1, 2, 3, 4, 5]
lowest from [1, 2, 3, 4, 5] is 1, removing
done initializing [1, 2, 3, 4, 5] to #<SortedSetWithoutLowest: {2, 3, 4, 5}>
lowest from [1, 2, 3, 4, 5] is 2, removing
done initializing [1, 2, 3, 4, 5] to #<SortedSetWithoutLowest: {3, 4, 5}>
initialize, [1, 2, 3, 4, 5]
lowest from [1, 2, 3, 4, 5] is 1, removing
done initializing [1, 2, 3, 4, 5] to #<SortedSetWithoutLowest: {2, 3, 4, 5}>
initialize, [1, 2, 3, 4, 5]
lowest from [1, 2, 3, 4, 5] is 1, removing
done initializing [1, 2, 3, 4, 5] to #<SortedSetWithoutLowest: {2, 3, 4, 5}>
```

The first such set created ends up with only [3, 4, 5], because SortedSet does some setup and then re-calls initialize (`set.rb` line 807). All further such sets are fine. All the sets are fine if any SortedSet has been made before, so calling `SortedSet.new` in the subclass's `initialize` and discarding the result is a viable workaround.

---Files--------------------------------
sorted-set-initialize.patch (944 Bytes)


-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>