Skip to content

Commit 987c1d8

Browse files
knuheadius
authored andcommitted
Merging fix from ruby_1_8 branch for bug ruby#118.
* lib/set.rb (SortedSet#add): Do not let an uncomparable object in. [Bug ruby#118] * lib/set.rb (Set#merge): Only directly use the passed objects @hash instance variable when self and the passed object are instances of the same class. [Bug ruby#118] * Original: e872e1d git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@23322 b2dd03c8-39d4-4d8f-98ff-823fe69b080e Signed-off-by: Charles Oliver Nutter <[email protected]>
1 parent 6d83962 commit 987c1d8

File tree

1 file changed

+40
-6
lines changed

1 file changed

+40
-6
lines changed

lib/set.rb

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#
2121
# The method +to_set+ is added to Enumerable for convenience.
2222
#
23-
# See the Set class for an example of usage.
23+
# See the Set and SortedSet documentation for examples of usage.
2424

2525

2626
#
@@ -257,8 +257,8 @@ def reject!
257257
# Merges the elements of the given enumerable object to the set and
258258
# returns self.
259259
def merge(enum)
260-
if enum.is_a?(Set)
261-
@hash.update(enum.instance_eval { @hash })
260+
if enum.instance_of?(self.class)
261+
@hash.update(enum.instance_variable_get(:@hash))
262262
else
263263
enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
264264
enum.each { |o| add(o) }
@@ -434,7 +434,35 @@ def pretty_print_cycle(pp) # :nodoc:
434434
end
435435
end
436436

437-
# SortedSet implements a set which elements are sorted in order. See Set.
437+
#
438+
# SortedSet implements a Set that guarantees that it's element are
439+
# yielded in sorted order (according to the return values of their
440+
# #<=> methods) when iterating over them.
441+
#
442+
# All elements that are added to a SortedSet must include the
443+
# Comparable module.
444+
#
445+
# Also, all elements must be <em>mutually comparable</em>: <tt>el1 <=>
446+
# el2</tt> must not return <tt>nil</tt> for any elements <tt>el1</tt>
447+
# and <tt>el2</tt>, else an ArgumentError will be raised when
448+
# iterating over the SortedSet.
449+
#
450+
# == Example
451+
#
452+
# require "set"
453+
#
454+
# set = SortedSet.new(2, 1, 5, 6, 4, 5, 3, 3, 3)
455+
# ary = []
456+
#
457+
# set.each do |obj|
458+
# ary << obj
459+
# end
460+
#
461+
# p ary # => [1, 2, 3, 4, 5, 6]
462+
#
463+
# set2 = SortedSet.new(1, 2, "3")
464+
# set2.each { |obj| } # => raises ArgumentError: comparison of Fixnum with String failed
465+
#
438466
class SortedSet < Set
439467
@@setup = false
440468

@@ -459,6 +487,12 @@ def initialize(*args, &block)
459487
@hash = RBTree.new
460488
super
461489
end
490+
491+
def add(o)
492+
o.is_a?(Comparable) or raise ArgumentError, "value must be comparable"
493+
super
494+
end
495+
alias << add
462496
}
463497
rescue LoadError
464498
module_eval %{
@@ -478,9 +512,9 @@ def replace(enum)
478512
end
479513
480514
def add(o)
515+
o.is_a?(Comparable) or raise ArgumentError, "value must be comparable"
481516
@keys = nil
482-
@hash[o] = true
483-
self
517+
super
484518
end
485519
alias << add
486520

0 commit comments

Comments
 (0)