* lib/set.rb: Fix a bug in flatten()'s recursive set detection.

[Submitted by: "Christoph" <chr_news@gmx.net>]  Some tests
  against the bug are added.

* lib/set.rb: Resurrect the test suite by putting it after
  __END__ and executing `eval DATA.read'.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2813 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
knu 2002-09-07 10:32:23 +00:00
parent 7622095d17
commit 6954ba398a
2 changed files with 396 additions and 356 deletions

View File

@ -1,3 +1,12 @@
Sat Sep 7 19:23:56 2002 Akinori MUSHA <knu@iDaemons.org>
* lib/set.rb: Fix a bug in flatten()'s recursive set detection.
[Submitted by: "Christoph" <chr_news@gmx.net>] Some tests
against the bug are added.
* lib/set.rb: Resurrect the test suite by putting it after
__END__ and executing `eval DATA.read'.
Sat Sep 7 08:41:39 2002 Minero Aoki <aamine@loveruby.net> Sat Sep 7 08:41:39 2002 Minero Aoki <aamine@loveruby.net>
* parse.y (rb_gc_mark_parser): ruby_eval_tree is marked in eval.c. * parse.y (rb_gc_mark_parser): ruby_eval_tree is marked in eval.c.
@ -91,6 +100,14 @@ Thu Sep 5 01:24:26 2002 WATANABE Hirofumi <eban@ruby-lang.org>
* mkmf.rb ($CPP): remove '-E' option. add CPPFLAGS. * mkmf.rb ($CPP): remove '-E' option. add CPPFLAGS.
Wed Sep 4 16:15:17 2002 Akinori MUSHA <knu@iDaemons.org>
* lib/set.rb: ==(o) should be aware of all the Set variant
instances, not just those of its subclasses. [Submitted by:
"Christoph" <chr_news@gmx.net>]
* lib/set.rb: - Fix eql?(). [ditto]
Wed Sep 4 15:23:23 2002 Yukihiro Matsumoto <matz@ruby-lang.org> Wed Sep 4 15:23:23 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
* class.c (rb_make_metaclass): obj.meta.super.meta should be equal * class.c (rb_make_metaclass): obj.meta.super.meta should be equal

View File

@ -225,34 +225,35 @@ class Set
@hash.keys @hash.keys
end end
def _flatten(set, ids = type.new, result = type.new) def flatten_merge(set, seen = Set.new)
setid = set.id set.each { |e|
if e.is_a?(Set)
if seen.include?(e_id = e.id)
raise ArgumentError, "tried to flatten recursive Set"
end
ids.include?(setid) and raise ArgumentError, "tried to flatten recursive #{type.name}" seen.add(e_id)
flatten_merge(e, seen)
ids.add(setid) seen.delete(e_id)
set.each { |o|
if o.is_a?(type)
_flatten(o, ids, result)
else else
result.add(o) add(e)
end end
} }
result self
end end
private :_flatten protected :flatten_merge
def flatten def flatten
_flatten(self) type.new.flatten_merge(self)
end end
def flatten! def flatten!
ids = type.new if detect { |e| e.is_a?(Set) }
replace(_flatten(self, ids)) replace(flatten())
else
ids.size == 1 ? nil : self nil
end
end end
def include?(o) def include?(o)
@ -428,12 +429,16 @@ class Set
end end
end end
=begin
if $0 == __FILE__ if $0 == __FILE__
require 'test/unit' eval DATA.read
require 'test/unit/ui/console/testrunner' end
class TC_Set < Test::Unit::TestCase __END__
require 'test/unit'
require 'test/unit/ui/console/testrunner'
class TC_Set < Test::Unit::TestCase
def test_aref def test_aref
assert_nothing_raised { assert_nothing_raised {
Set[] Set[]
@ -526,6 +531,7 @@ if $0 == __FILE__
end end
def test_flatten def test_flatten
# test1
set1 = Set[ set1 = Set[
1, 1,
Set[ Set[
@ -546,12 +552,31 @@ if $0 == __FILE__
assert_not_same(set2, set1) assert_not_same(set2, set1)
assert_equal(set3, set2) assert_equal(set3, set2)
# destructive # test2; destructive
orig_set1 = set1 orig_set1 = set1
set1.flatten! set1.flatten!
assert_same(orig_set1, set1) assert_same(orig_set1, set1)
assert_equal(set3, set1) assert_equal(set3, set1)
# test3; multiple occurences of a set in an set
set1 = Set[1, 2]
set2 = Set[set1, Set[set1, 4], 3]
assert_nothing_raised {
set2.flatten!
}
assert_equal(Set.new(1..4), set2)
# test4; recursion
set2 = Set[]
set1 = Set[1, set2]
set2.add(set1)
assert_raises(ArgumentError) {
set1.flatten!
}
end end
def test_include? def test_include?
@ -771,8 +796,6 @@ if $0 == __FILE__
# def test_pretty_print_cycled # def test_pretty_print_cycled
# end # end
end
Test::Unit::UI::Console::TestRunner.run(TC_Set)
end end
=end
Test::Unit::UI::Console::TestRunner.run(TC_Set)