Skip to content

Commit e872e1d

Browse files
committed
* 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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@23322 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 62ee2b4 commit e872e1d

File tree

2 files changed

+49
-6
lines changed

2 files changed

+49
-6
lines changed

ChangeLog

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
Fri May 1 16:52:52 2009 Akinori MUSHA <[email protected]>
2+
3+
* lib/set.rb (SortedSet#add): Do not let an uncomparable object
4+
in. [Bug #118]
5+
6+
* lib/set.rb (Set#merge): Only directly use the passed objects
7+
@hash instance variable when self and the passed object are
8+
instances of the same class. [Bug #118]
9+
110
Fri May 1 16:01:31 2009 Nobuyoshi Nakada <[email protected]>
211

312
* configure.in: fixed the help strings for the header and library

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
#
@@ -260,8 +260,8 @@ def reject!
260260
# Merges the elements of the given enumerable object to the set and
261261
# returns self.
262262
def merge(enum)
263-
if enum.is_a?(Set)
264-
@hash.update(enum.instance_eval { @hash })
263+
if enum.instance_of?(self.class)
264+
@hash.update(enum.instance_variable_get(:@hash))
265265
else
266266
enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
267267
enum.each { |o| add(o) }
@@ -441,7 +441,35 @@ def pretty_print_cycle(pp) # :nodoc:
441441
end
442442
end
443443

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

@@ -466,6 +494,12 @@ def initialize(*args, &block)
466494
@hash = RBTree.new
467495
super
468496
end
497+
498+
def add(o)
499+
o.is_a?(Comparable) or raise ArgumentError, "value must be comparable"
500+
super
501+
end
502+
alias << add
469503
}
470504
rescue LoadError
471505
module_eval %{
@@ -485,9 +519,9 @@ def replace(enum)
485519
end
486520
487521
def add(o)
522+
o.is_a?(Comparable) or raise ArgumentError, "value must be comparable"
488523
@keys = nil
489-
@hash[o] = true
490-
self
524+
super
491525
end
492526
alias << add
493527

0 commit comments

Comments
 (0)