Skip to content
This repository was archived by the owner on Apr 15, 2026. It is now read-only.

Commit bddcf30

Browse files
authored
Merge pull request #2 from ruby/remove_sorted_set
Remove SortedSet implementations
2 parents 72f08c4 + dfcc8e5 commit bddcf30

2 files changed

Lines changed: 1 addition & 364 deletions

File tree

lib/set.rb

Lines changed: 1 addition & 246 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,9 @@
1616
#
1717
# This library provides the Set class, which deals with a collection
1818
# of unordered values with no duplicates. It is a hybrid of Array's
19-
# intuitive inter-operation facilities and Hash's fast lookup. If you
20-
# need to keep values sorted in some order, use the SortedSet class.
19+
# intuitive inter-operation facilities and Hash's fast lookup.
2120
#
2221
# The method +to_set+ is added to Enumerable for convenience.
23-
#
24-
# See the Set and SortedSet documentation for examples of usage.
2522

2623

2724
#
@@ -667,252 +664,10 @@ def pretty_print_cycle(pp) # :nodoc:
667664
end
668665
end
669666

670-
#
671-
# SortedSet implements a Set that guarantees that its elements are
672-
# yielded in sorted order (according to the return values of their
673-
# #<=> methods) when iterating over them.
674-
#
675-
# All elements that are added to a SortedSet must respond to the <=>
676-
# method for comparison.
677-
#
678-
# Also, all elements must be <em>mutually comparable</em>: <tt>el1 <=>
679-
# el2</tt> must not return <tt>nil</tt> for any elements <tt>el1</tt>
680-
# and <tt>el2</tt>, else an ArgumentError will be raised when
681-
# iterating over the SortedSet.
682-
#
683-
# == Example
684-
#
685-
# require "set"
686-
#
687-
# set = SortedSet.new([2, 1, 5, 6, 4, 5, 3, 3, 3])
688-
# ary = []
689-
#
690-
# set.each do |obj|
691-
# ary << obj
692-
# end
693-
#
694-
# p ary # => [1, 2, 3, 4, 5, 6]
695-
#
696-
# set2 = SortedSet.new([1, 2, "3"])
697-
# set2.each { |obj| } # => raises ArgumentError: comparison of Fixnum with String failed
698-
#
699-
class SortedSet < Set
700-
@@setup = false
701-
@@mutex = Mutex.new
702-
703-
class << self
704-
def [](*ary) # :nodoc:
705-
new(ary)
706-
end
707-
708-
def setup # :nodoc:
709-
@@setup and return
710-
711-
@@mutex.synchronize do
712-
# a hack to shut up warning
713-
alias_method :old_init, :initialize
714-
715-
begin
716-
require 'rbtree'
717-
718-
module_eval <<-END, __FILE__, __LINE__+1
719-
def initialize(*args)
720-
@hash = RBTree.new
721-
super
722-
end
723-
724-
def add(o)
725-
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
726-
super
727-
end
728-
alias << add
729-
END
730-
rescue LoadError
731-
module_eval <<-END, __FILE__, __LINE__+1
732-
def initialize(*args)
733-
@keys = nil
734-
super
735-
end
736-
737-
def clear
738-
@keys = nil
739-
super
740-
end
741-
742-
def replace(enum)
743-
@keys = nil
744-
super
745-
end
746-
747-
def add(o)
748-
o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
749-
@keys = nil
750-
super
751-
end
752-
alias << add
753-
754-
def delete(o)
755-
@keys = nil
756-
@hash.delete(o)
757-
self
758-
end
759-
760-
def delete_if
761-
block_given? or return enum_for(__method__) { size }
762-
n = @hash.size
763-
super
764-
@keys = nil if @hash.size != n
765-
self
766-
end
767-
768-
def keep_if
769-
block_given? or return enum_for(__method__) { size }
770-
n = @hash.size
771-
super
772-
@keys = nil if @hash.size != n
773-
self
774-
end
775-
776-
def merge(enum)
777-
@keys = nil
778-
super
779-
end
780-
781-
def each(&block)
782-
block or return enum_for(__method__) { size }
783-
to_a.each(&block)
784-
self
785-
end
786-
787-
def to_a
788-
(@keys = @hash.keys).sort! unless @keys
789-
@keys.dup
790-
end
791-
792-
def freeze
793-
to_a
794-
super
795-
end
796-
797-
def rehash
798-
@keys = nil
799-
super
800-
end
801-
END
802-
end
803-
# a hack to shut up warning
804-
remove_method :old_init
805-
806-
@@setup = true
807-
end
808-
end
809-
end
810-
811-
def initialize(*args, &block) # :nodoc:
812-
SortedSet.setup
813-
@keys = nil
814-
super
815-
end
816-
end
817-
818667
module Enumerable
819668
# Makes a set from the enumerable object with given arguments.
820669
# Needs to +require "set"+ to use this method.
821670
def to_set(klass = Set, *args, &block)
822671
klass.new(self, *args, &block)
823672
end
824673
end
825-
826-
# =begin
827-
# == RestricedSet class
828-
# RestricedSet implements a set with restrictions defined by a given
829-
# block.
830-
#
831-
# === Super class
832-
# Set
833-
#
834-
# === Class Methods
835-
# --- RestricedSet::new(enum = nil) { |o| ... }
836-
# --- RestricedSet::new(enum = nil) { |rset, o| ... }
837-
# Creates a new restricted set containing the elements of the given
838-
# enumerable object. Restrictions are defined by the given block.
839-
#
840-
# If the block's arity is 2, it is called with the RestrictedSet
841-
# itself and an object to see if the object is allowed to be put in
842-
# the set.
843-
#
844-
# Otherwise, the block is called with an object to see if the object
845-
# is allowed to be put in the set.
846-
#
847-
# === Instance Methods
848-
# --- restriction_proc
849-
# Returns the restriction procedure of the set.
850-
#
851-
# =end
852-
#
853-
# class RestricedSet < Set
854-
# def initialize(*args, &block)
855-
# @proc = block or raise ArgumentError, "missing a block"
856-
#
857-
# if @proc.arity == 2
858-
# instance_eval %{
859-
# def add(o)
860-
# @hash[o] = true if @proc.call(self, o)
861-
# self
862-
# end
863-
# alias << add
864-
#
865-
# def add?(o)
866-
# if include?(o) || !@proc.call(self, o)
867-
# nil
868-
# else
869-
# @hash[o] = true
870-
# self
871-
# end
872-
# end
873-
#
874-
# def replace(enum)
875-
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
876-
# clear
877-
# enum.each_entry { |o| add(o) }
878-
#
879-
# self
880-
# end
881-
#
882-
# def merge(enum)
883-
# enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
884-
# enum.each_entry { |o| add(o) }
885-
#
886-
# self
887-
# end
888-
# }
889-
# else
890-
# instance_eval %{
891-
# def add(o)
892-
# if @proc.call(o)
893-
# @hash[o] = true
894-
# end
895-
# self
896-
# end
897-
# alias << add
898-
#
899-
# def add?(o)
900-
# if include?(o) || !@proc.call(o)
901-
# nil
902-
# else
903-
# @hash[o] = true
904-
# self
905-
# end
906-
# end
907-
# }
908-
# end
909-
#
910-
# super(*args)
911-
# end
912-
#
913-
# def restriction_proc
914-
# @proc
915-
# end
916-
# end
917-
918-
# Tests have been moved to test/test_set.rb.

test/test_set.rb

Lines changed: 0 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -796,116 +796,6 @@ def test_reset
796796
end
797797
end
798798

799-
class TC_SortedSet < Test::Unit::TestCase
800-
def test_sortedset
801-
s = SortedSet[4,5,3,1,2]
802-
803-
a = s.to_a
804-
assert_equal([1,2,3,4,5], a)
805-
a << -1
806-
assert_equal([1,2,3,4,5], s.to_a)
807-
808-
prev = nil
809-
s.each { |o| assert(prev < o) if prev; prev = o }
810-
assert_not_nil(prev)
811-
812-
s.map! { |o| -2 * o }
813-
814-
assert_equal([-10,-8,-6,-4,-2], s.to_a)
815-
816-
prev = nil
817-
ret = s.each { |o| assert(prev < o) if prev; prev = o }
818-
assert_not_nil(prev)
819-
assert_same(s, ret)
820-
821-
s = SortedSet.new([2,1,3]) { |o| o * -2 }
822-
assert_equal([-6,-4,-2], s.to_a)
823-
824-
s = SortedSet.new(['one', 'two', 'three', 'four'])
825-
a = []
826-
ret = s.delete_if { |o| a << o; o.start_with?('t') }
827-
assert_same(s, ret)
828-
assert_equal(['four', 'one'], s.to_a)
829-
assert_equal(['four', 'one', 'three', 'two'], a)
830-
831-
s = SortedSet.new(['one', 'two', 'three', 'four'])
832-
a = []
833-
ret = s.reject! { |o| a << o; o.start_with?('t') }
834-
assert_same(s, ret)
835-
assert_equal(['four', 'one'], s.to_a)
836-
assert_equal(['four', 'one', 'three', 'two'], a)
837-
838-
s = SortedSet.new(['one', 'two', 'three', 'four'])
839-
a = []
840-
ret = s.reject! { |o| a << o; false }
841-
assert_same(nil, ret)
842-
assert_equal(['four', 'one', 'three', 'two'], s.to_a)
843-
assert_equal(['four', 'one', 'three', 'two'], a)
844-
end
845-
846-
def test_each
847-
ary = [1,3,5,7,10,20]
848-
set = SortedSet.new(ary)
849-
850-
ret = set.each { |o| }
851-
assert_same(set, ret)
852-
853-
e = set.each
854-
assert_instance_of(Enumerator, e)
855-
856-
assert_nothing_raised {
857-
set.each { |o|
858-
ary.delete(o) or raise "unexpected element: #{o}"
859-
}
860-
861-
ary.empty? or raise "forgotten elements: #{ary.join(', ')}"
862-
}
863-
864-
assert_equal(6, e.size)
865-
set << 42
866-
assert_equal(7, e.size)
867-
end
868-
869-
def test_freeze
870-
orig = set = SortedSet[3,2,1]
871-
assert_equal false, set.frozen?
872-
set << 4
873-
assert_same orig, set.freeze
874-
assert_equal true, set.frozen?
875-
assert_raise(FrozenError) {
876-
set << 5
877-
}
878-
assert_equal 4, set.size
879-
880-
# https://bugs.ruby-lang.org/issues/12091
881-
assert_nothing_raised {
882-
assert_equal [1,2,3,4], set.to_a
883-
}
884-
end
885-
886-
def test_freeze_dup
887-
set1 = SortedSet[1,2,3]
888-
set1.freeze
889-
set2 = set1.dup
890-
891-
assert_not_predicate set2, :frozen?
892-
assert_nothing_raised {
893-
set2.add 4
894-
}
895-
end
896-
897-
def test_freeze_clone
898-
set1 = SortedSet[1,2,3]
899-
set1.freeze
900-
set2 = set1.clone
901-
902-
assert_predicate set2, :frozen?
903-
assert_raise(FrozenError) {
904-
set2.add 5
905-
}
906-
end
907-
end
908-
909799
class TC_Enumerable < Test::Unit::TestCase
910800
def test_to_set
911801
ary = [2,5,4,3,2,1,3]
@@ -920,13 +810,5 @@ def test_to_set
920810

921811
assert_same set, set.to_set
922812
assert_not_same set, set.to_set { |o| o }
923-
924-
set = ary.to_set(SortedSet)
925-
assert_instance_of(SortedSet, set)
926-
assert_equal([1,2,3,4,5], set.to_a)
927-
928-
set = ary.to_set(SortedSet) { |o| o * -2 }
929-
assert_instance_of(SortedSet, set)
930-
assert_equal([-10,-8,-6,-4,-2], set.sort)
931813
end
932814
end

0 commit comments

Comments
 (0)