Index: lib/set.rb =================================================================== --- lib/set.rb (Revision 17065) +++ lib/set.rb (Arbeitskopie) @@ -14,13 +14,13 @@ # == Overview # # This library provides the Set class, which deals with a collection -# of unordered values with no duplicates. It is a hybrid of Array's +# of unordered values with no duplicates. It is a hybrid of Array's # intuitive inter-operation facilities and Hash's fast lookup. If you # need to keep values ordered, use the SortedSet class. # # The method +to_set+ is added to Enumerable for convenience. # -# See the Set class for an example of usage. +# See the Set and SortedSet documentation for examples of usage. # @@ -257,8 +257,8 @@ # Merges the elements of the given enumerable object to the set and # returns self. def merge(enum) - if enum.is_a?(Set) - @hash.update(enum.instance_eval { @hash }) + if enum.instance_of? self.class + @hash.update(enum.instance_variable_get(:@hash)) else enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable" enum.each { |o| add(o) } @@ -434,7 +434,34 @@ end end -# SortedSet implements a set which elements are sorted in order. See Set. +# +# SortedSet implements a Set that guarantees that it's element are +# yielded in sorted order (according to the return values of their #<=> methods) +# when iterating over them. +# +# All elements that are added to a SortedSet must include the Comparable module. +# +# Also, all elements must be mutually comparable: +# el1 <=> el2 must not return nil for any elements +# el1 and el2, else an ArgumentError will be raised +# when iterating over the SortedSet. +# +# == Example +# +# require "set" +# +# set = SortedSet.new(2, 1, 5, 6, 4, 5, 3, 3, 3) +# ary = [] +# +# set.each do |obj| +# ary << obj +# end +# +# p ary # => [1, 2, 3, 4, 5, 6] +# +# set2 = SortedSet.new(1, 2, "3") +# set2.each { |obj| } # => raises ArgumentError: comparison of Fixnum with String failed +# class SortedSet < Set @@setup = false @@ -459,6 +486,12 @@ @hash = RBTree.new super end + + def add(obj) + obj.is_a?(Comparable) or raise ArgumentError, "value must be comparable" + super + end + alias << add } rescue LoadError module_eval %{ @@ -477,10 +510,10 @@ super end - def add(o) + def add(obj) + obj.is_a?(Comparable) or raise ArgumentError, "value must be comparable" @keys = nil - @hash[o] = true - self + super end alias << add