Add 'mrbgems/mruby-set/' from commit '68334311ac7386eef84f3034a256e7135a87625d'
authorYukihiro "Matz" Matsumoto <[email protected]>
Fri, 21 Oct 2022 04:56:07 +0000 (21 13:56 +0900)
committerYukihiro "Matz" Matsumoto <[email protected]>
Fri, 21 Oct 2022 04:56:07 +0000 (21 13:56 +0900)
git-subtree-dir: mrbgems/mruby-set
git-subtree-mainline: 3b55a09f919e37b1ed9babc4c54ec5671ccdb421
git-subtree-split: 68334311ac7386eef84f3034a256e7135a87625d

1  2 
mrbgems/mruby-set/.gitignore
mrbgems/mruby-set/.travis.yml
mrbgems/mruby-set/LICENSE
mrbgems/mruby-set/README.md
mrbgems/mruby-set/Rakefile
mrbgems/mruby-set/build_config.rb
mrbgems/mruby-set/mrbgem.rake
mrbgems/mruby-set/mrblib/mrb_set.rb
mrbgems/mruby-set/mruby-set.gem
mrbgems/mruby-set/test/mrb_set.rb

index 0000000,b349187..b349187
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,1 +1,1 @@@
+ /mruby/
index 0000000,4cb8c74..4cb8c74
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,14 +1,14 @@@
+ sudo: false
+ addons:
+   apt:
+     packages:
+       - rake
+       - bison
+       - git
+       - gperf
+ language: c
+ compiler:
+   - gcc
+   - clang
+ script: 
+   - rake test
index 0000000,c88fed2..c88fed2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,25 +1,25 @@@
+ mruby-set
+ Copyright (c) yui-knk 2016
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
index 0000000,616bd3e..616bd3e
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,47 +1,47 @@@
+ # mruby-set   [![Build Status](https://travis-ci.org/yui-knk/mruby-set.png?branch=master)](https://travis-ci.org/yui-knk/mruby-set)
+ Set class
+ ## install by mrbgems 
+ - add conf.gem line to `build_config.rb` 
+ ```ruby
+ MRuby::Build.new do |conf|
+   # ... (snip) ...
+   conf.gem :git => 'https://github.com/yui-knk/mruby-set.git'
+ end
+ ```
+ ## example 
+ ```ruby
+ set1 = Set.new([1,2])
+ set2 = Set[1,2,3]
+ set3 = Set[4]
+ set1 + set3
+ #=> #<Set: {1, 2, 4}>
+ set2 - set1
+ #=> #<Set: {3}>
+ set2 & set1
+ #=> #<Set: {1, 2}>
+ set1 ^ set2
+ #=> #<Set: {3}>
+ ```
+ ## limitation
+ These methods are not implemented yet.
+ + freeze
+ + taint
+ + untaint
+ + to_set
+ + divide(Set#divide with 2 arity block is not implemented.)
+ ## License
+ under the MIT License:
+ - see LICENSE file
index 0000000,af775b8..af775b8
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,22 +1,22 @@@
+ MRUBY_CONFIG = File.expand_path(ENV["MRUBY_CONFIG"] || "build_config.rb")
+ file :mruby do
+   sh "git clone --depth=1 git://github.com/mruby/mruby.git"
+ end
+ desc "compile binary"
+ task :compile => :mruby do
+   sh "cd mruby && MRUBY_CONFIG=#{MRUBY_CONFIG} rake all"
+ end
+ desc "test"
+ task :test => :mruby do
+   sh "cd mruby && MRUBY_CONFIG=#{MRUBY_CONFIG} rake all test"
+ end
+ desc "cleanup"
+ task :clean do
+   sh "cd mruby && rake deep_clean"
+ end
+ task :default => :test
index 0000000,9568b5c..9568b5c
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,6 +1,6 @@@
+ MRuby::Build.new do |conf|
+   toolchain :gcc
+   conf.gembox 'default'
+   conf.gem '../mruby-set'
+   conf.enable_test
+ end
index 0000000,c593057..c593057
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,7 +1,7 @@@
+ MRuby::Gem::Specification.new('mruby-set') do |spec|
+   spec.license = 'MIT'
+   spec.authors = 'yui-knk'
+   spec.add_dependency "mruby-hash-ext", :core => "mruby-hash-ext"
+   spec.add_dependency "mruby-enumerator", :core => "mruby-enumerator"
+ end
index 0000000,dbf77b9..dbf77b9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,313 +1,313 @@@
+ class Set
+   include Enumerable
+   def self.[](*ary)
+     new(ary)
+   end
+   def initialize(enum = nil, &block)
+     @hash ||= Hash.new
+     enum.nil? and return
+     if block_given?
+       do_with_enum(enum) { |o| add(block.call(o)) }
+     else
+       merge(enum)
+     end
+   end
+   def do_with_enum(enum, &block)
+     if enum.respond_to?(:each)
+       enum.each(&block)
+     else
+       raise ArgumentError, "value must be enumerable"
+     end
+   end
+   private :do_with_enum
+   def initialize_copy(orig)
+     super
+     @hash = orig.instance_variable_get(:@hash).dup
+   end
+   # def initialize_dup(orig)
+   #   super
+   #   @hash = orig.instance_variable_get(:@hash).dup
+   # end
+   # def initialize_clone(orig)
+   #   super
+   #   @hash = orig.instance_variable_get(:@hash).clone
+   # end
+   # def freeze
+   #   @hash.freeze
+   #   super
+   # end
+   # def taint
+   #   @hash.taint
+   #   super
+   # end
+   # def untaint
+   #   @hash.untaint
+   #   super
+   # end
+   def size
+     @hash.size
+   end
+   alias length size
+   def empty?
+     @hash.empty?
+   end
+   def clear
+     @hash.clear
+     self
+   end
+   def replace(enum)
+     clear
+     merge(enum)
+   end
+   def to_a
+     @hash.keys
+   end
+ #  def to_set
+ #  end
+ #
+   def flatten_merge(set, seen = Set.new)
+     seen.add(set.object_id)
+     set.each { |e|
+       if e.is_a?(Set)
+         if seen.include?(e_id = e.object_id)
+           raise ArgumentError, "tried to flatten recursive Set"
+         end
+         flatten_merge(e, seen)
+       else
+         add(e)
+       end
+     }
+     seen.delete(set.object_id)
+     self
+   end
+   def flatten
+     self.class.new.flatten_merge(self)
+   end
+   def flatten!
+     if detect { |e| e.is_a?(Set) }
+       replace(flatten())
+     else
+       nil
+     end
+   end
+   def include?(o)
+     @hash.include?(o)
+   end
+   alias member? include?
+   def superset?(set)
+     raise ArgumentError, "value must be a set" unless set.is_a?(Set)
+     return false if size < set.size
+     set.all? { |o| include?(o) }
+   end
+   alias >= superset?
+   def proper_superset?(set)
+     raise ArgumentError, "value must be a set" unless set.is_a?(Set)
+     return false if size <= set.size
+     set.all? { |o| include?(o) }
+   end
+   alias > proper_superset?
+   def subset?(set)
+     raise ArgumentError, "value must be a set" unless set.is_a?(Set)
+     set.superset?(self)
+   end
+   alias <= subset?
+   def proper_subset?(set)
+     raise ArgumentError, "value must be a set" unless set.is_a?(Set)
+     set.proper_superset?(self)
+   end
+   alias < proper_subset?
+   def intersect?(set)
+     raise ArgumentError, "value must be a set" unless set.is_a?(Set)
+     if size < set.size
+       any? { |o| set.include?(o) }
+     else
+       set.any? { |o| include?(o) }
+     end
+   end
+  def disjoint?(set)
+   !intersect?(set)
+  end
+   def each(&block)
+     return to_enum :each unless block_given?
+     @hash.each_key(&block)
+     self
+   end
+   def add(o)
+     @hash[o] = true
+     self
+   end
+   alias << add
+   def add?(o)
+     if include?(o)
+       nil
+     else
+       add(o)
+     end
+   end
+   def delete(o)
+     @hash.delete(o)
+     self
+   end
+   def delete?(o)
+     if include?(o)
+       delete(o)
+     else
+       nil
+     end
+   end
+   def delete_if
+     return to_enum :delete_if unless block_given?
+     select { |o| yield o }.each { |o| @hash.delete(o) }
+     self
+   end
+   def keep_if
+     return to_enum :keep_if unless block_given?
+     reject { |o| yield o }.each { |o| @hash.delete(o) }
+     self
+   end
+   def collect!
+    return to_enum :collect! unless block_given?
+    set = self.class.new
+    each { |o| set << yield(o) }
+    replace(set)
+   end
+   alias map! collect!
+   def reject!(&block)
+     return to_enum :reject! unless block_given?
+     n = size
+     delete_if(&block)
+     size == n ? nil : self
+   end
+   def select!(&block)
+     return to_enum :select! unless block_given?
+     n = size
+     keep_if(&block)
+     size == n ? nil : self
+   end
+   def merge(enum)
+     if enum.instance_of?(self.class)
+       @hash.merge!(enum.instance_variable_get(:@hash))
+     else
+       do_with_enum(enum) { |o| add(o) }
+     end
+     self
+   end
+   def subtract(enum)
+     do_with_enum(enum) { |o| delete(o) }
+     self
+   end
+   def |(enum)
+     dup.merge(enum)
+   end
+   alias + |
+   alias union |
+   def -(enum)
+     dup.subtract(enum)
+   end
+   alias difference -
+   def &(enum)
+     n = Set.new
+     do_with_enum(enum) { |o| n.add(o) if include?(o) }
+     n
+   end
+   alias intersection &
+   def ^(enum)
+     (self | Set.new(enum)) - (self & Set.new(enum))
+   end
+   def ==(other)
+     if self.equal?(other)
+       true
+     elsif other.instance_of?(self.class) && self.size == other.size
+       other_hash = other.instance_variable_get(:@hash)
+       other_hash.keys.all? { |o| @hash.keys.include?(o) }
+       other_hash.values.all? { |o| @hash.values.include?(o) }
+ #      @hash == other.instance_variable_get(:@hash)
+     elsif other.is_a?(self.class) && self.size == other.size
+       other.all? { |o| include?(o) }
+     else
+       false
+     end
+   end
+   def hash
+     @hash.hash
+   end
+   def eql?(o)
+     return false unless o.is_a?(Set)
+     @hash.eql?(o.instance_variable_get(:@hash))
+   end
+   def classify
+     return to_enum :classify unless block_given?
+     h = {}
+     each { |i|
+       x = yield(i)
+       (h[x] ||= self.class.new).add(i)
+     }
+     h
+   end
+   def divide(&func)
+     return to_enum :divide unless block_given?
+     if func.arity == 2
+       raise NotImplementedError, "Set#divide with 2 arity block is not implemented."
+     end
+     Set.new(classify(&func).values)
+   end
+   def inspect
+     "#<#{self.class}: {#{self.to_a.inspect[1..-2]}}>"
+   end
+ end
index 0000000,84a4afb..84a4afb
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,6 +1,6 @@@
+ name: mruby-set
+ description: Set class
+ author: yui-knk
+ website: https://github.com/yui-knk/mruby-set
+ protocol: git
+ repository: https://github.com/yui-knk/mruby-set.git
index 0000000,d8c8381..d8c8381
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,642 +1,642 @@@
+ ##  
+ ## Set Test
+ ##
+ assert("Set.new") do
+   assert_nothing_raised {
+     Set.new()
+     Set.new(nil)
+     Set.new([])
+     Set.new([1,2])
+     Set.new(1..3)
+   }
+   assert_raise(ArgumentError) { Set.new(false) }
+   assert_raise(ArgumentError) { Set.new(1) }
+   assert_raise(ArgumentError) { Set.new(1,2) }
+   ary = [2,4,6,4]
+   set = Set.new(ary)
+   ary.clear
+   assert_false set.empty?
+   assert_equal(3, set.size)
+   ary = [1,2,3]
+   s = Set.new(ary) { |o| o * 2 }
+   assert_equal([2,4,6], s.sort)
+ end
+ assert("Set.[]") do
+   assert_nothing_raised {
+     Set[]
+     Set[nil]
+     Set[[]]
+     Set[[1,2]]
+     Set['a'..'c']
+     Set[false]
+     Set[1]
+     Set[1,2]
+   }
+   ary = [2,4,6,4]
+   set = Set[ary]
+   ary.clear
+   assert_false set.empty?
+   assert_equal([[]], set.to_a)
+ end
+ assert("Set#clone") do
+   set1 = Set.new
+   set2 = set1.clone
+   assert_false set1.equal?(set2) # assert_not_same
+   assert_equal(set1, set2)
+   set1 << 'abc'
+   assert_equal(Set.new, set2)
+ end
+ assert("Set#dup") do
+   set1 = Set[1,2]
+   set2 = set1.dup
+   assert_false set1.equal?(set2) # assert_not_same
+   assert_equal(set1, set2)
+   set1 << 'abc'
+   assert_equal(Set[1,2], set2)
+ end
+ assert("Set#size") do
+   assert_equal(0, Set[].size)
+   assert_equal(1, Set[nil].size)
+   assert_equal(1, Set[[]].size)
+   assert_equal(1, Set[[nil]].size)
+ end
+ assert("Set#empty?") do
+   assert_true Set[].empty?
+   assert_false Set[1,2].empty?
+ end
+ assert("Set#clear") do
+   set = Set[1,2]
+   ret = set.clear
+   assert_true set.equal?(ret) # assert_same
+   assert_true set.empty?
+ end
+ assert("Set#replace") do
+   set = Set[1,2]
+   ret = set.replace(['a','b','c'])
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set['a','b','c'], set)
+   set = Set[1,2]
+   ret = set.replace(Set['a','b','c'])
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set['a','b','c'], set)
+ end
+ assert("Set#to_a") do
+   set = Set[1,2,3,2]
+   ary = set.to_a
+   assert_equal([1,2,3], ary.sort)
+ end
+ assert("Set#flatten") do
+   # test1
+   set1 = Set[
+     1,
+     Set[
+       5,
+       Set[7,
+         Set[0]
+       ],
+       Set[6,2],
+       1
+     ],
+     3,
+     Set[3,4]
+   ]
+   set2 = set1.flatten
+   set3 = Set.new(0..7)
+   assert_false set1.equal?(set2) # assert_not_same
+   assert_equal(set3, set2)
+   # test2; multiple occurrences of a set in an set
+   set1 = Set[1, 2]
+   set2 = Set[set1, Set[set1, 4], 3]
+   assert_nothing_raised {
+     set3 = set2.flatten
+   }
+   assert_equal(Set.new(1..4), set3)
+   # test3; recursion
+   set2 = Set[]
+   set1 = Set[1, set2]
+   set2.add(set1)
+   assert_raise(ArgumentError) {
+     set1.flatten
+   }
+   # test4; miscellaneous
+   empty = Set[]
+   set = Set[Set[empty, "a"], Set[empty, "b"]]
+   assert_nothing_raised {
+     set.flatten
+   }
+ end
+ assert("Set#flatten!") do
+   # test1
+   set1 = Set[
+     1,
+     Set[
+       5,
+       Set[7,
+         Set[0]
+       ],
+       Set[6,2],
+       1
+     ],
+     3,
+     Set[3,4]
+   ]
+   set3 = Set.new(0..7)
+   orig_set1 = set1
+   set1.flatten!
+   assert_true orig_set1.equal?(set1) # assert_same
+   assert_equal(set3, set1)
+   # test2; multiple occurrences 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)
+   # test3; recursion
+   set2 = Set[]
+   set1 = Set[1, set2]
+   set2.add(set1)
+   assert_raise(ArgumentError) {
+     set1.flatten!
+   }
+   # test4; miscellaneous
+   assert_nil(Set.new(0..31).flatten!)
+   x = Set[Set[],Set[1,2]].flatten!
+   y = Set[1,2]
+   assert_equal(x, y)
+ end
+ assert("Set#include?") do
+   set = Set[1,2,3]
+   assert_true set.include?(1)
+   assert_true set.include?(2)
+   assert_true set.include?(3)
+   assert_false set.include?(0)
+   assert_false set.include?(nil)
+   set = Set["1",nil,"2",nil,"0","1",false]
+   assert_true set.include?(nil)
+   assert_true set.include?(false)
+   assert_true set.include?("1")
+   assert_false set.include?(0)
+   assert_false set.include?(true)
+   assert_false set.include?(2)
+ end
+ assert("Set#superset?") do
+   set = Set[1,2,3]
+   assert_raise(ArgumentError) { set.superset?(nil) }
+   assert_raise(ArgumentError) { set.superset?(2) }
+   assert_raise(ArgumentError) { set.superset?([2]) }
+   assert_true set.superset?(Set[])
+   assert_true set.superset?(Set[1,2])
+   assert_true set.superset?(Set[1,2,3])
+   assert_false set.superset?(Set[1,2,3,4])
+   assert_false set.superset?(Set[1,4])
+   assert_true set >= Set[1,2]
+   assert_true set >= Set[1,2,3]
+   assert_true Set[].superset?(Set[])
+ end
+ assert("Set#proper_superset?") do
+   set = Set[1,2,3]
+   assert_raise(ArgumentError) { set.proper_superset?(nil) }
+   assert_raise(ArgumentError) { set.proper_superset?(2) }
+   assert_raise(ArgumentError) { set.proper_superset?([2]) }
+   assert_true set.proper_superset?(Set[])
+   assert_true set.proper_superset?(Set[1,2])
+   assert_false set.proper_superset?(Set[1,2,3])
+   assert_false set.proper_superset?(Set[1,2,3,4])
+   assert_false set.proper_superset?(Set[1,4])
+   assert_true set > Set[1,2]
+   assert_false set > Set[1,2,3]
+   assert_false Set[].proper_superset?(Set[])
+ end
+ assert("Set#subset?") do
+   set = Set[1,2,3]
+   assert_raise(ArgumentError) { set.subset?(nil) }
+   assert_raise(ArgumentError) { set.subset?(2) }
+   assert_raise(ArgumentError) { set.subset?([2]) }
+   assert_true set.subset?(Set[1,2,3,4])
+   assert_true set.subset?(Set[1,2,3])
+   assert_false set.subset?(Set[1,2])
+   assert_false set.subset?(Set[])
+   assert_true set <= Set[1,2,3]
+   assert_false set <= Set[1,2]
+   assert_true Set[].subset?(Set[1])
+   assert_true Set[].subset?(Set[])
+ end
+ assert("Set#proper_subset?") do
+   set = Set[1,2,3]
+   assert_raise(ArgumentError) { set.proper_subset?(nil) }
+   assert_raise(ArgumentError) { set.proper_subset?(2) }
+   assert_raise(ArgumentError) { set.proper_subset?([2]) }
+   assert_true set.proper_subset?(Set[1,2,3,4])
+   assert_false set.proper_subset?(Set[1,2,3])
+   assert_false set.proper_subset?(Set[1,2])
+   assert_false set.proper_subset?(Set[])
+   assert_true set < Set[1,2,3,4]
+   assert_false set < Set[1,2,3]
+   assert_true Set[].proper_subset?(Set[1])
+   assert_false Set[].proper_subset?(Set[])
+ end
+ assert("Set#intersect?") do
+   set = Set[3,4,5]
+   assert_raise(ArgumentError) { set.intersect?(3) }
+   assert_raise(ArgumentError) { set.intersect?([2,4,6]) }
+   assert_true set.intersect?(set)
+   assert_true set.intersect?(Set[2,4])
+   assert_true set.intersect?(Set[5,6,7])
+   assert_true set.intersect?(Set[1,2,6,8,4])
+   assert_false(set.intersect?(Set[]))
+   assert_false(set.intersect?(Set[0,2]))
+   assert_false(set.intersect?(Set[0,2,6]))
+   assert_false(set.intersect?(Set[0,2,6,8,10]))
+   # Make sure set hasn't changed
+   assert_equal(Set[3,4,5], set)
+ end
+ assert("Set#disjoint?") do
+   set = Set[3,4,5]
+   assert_raise(ArgumentError) { set.disjoint?(3) }
+   assert_raise(ArgumentError) { set.disjoint?([2,4,6]) }
+   assert_true(set.disjoint?(Set[]))
+   assert_true(set.disjoint?(Set[0,2]))
+   assert_true(set.disjoint?(Set[0,2,6]))
+   assert_true(set.disjoint?(Set[0,2,6,8,10]))
+   assert_false set.disjoint?(set)
+   assert_false set.disjoint?(Set[2,4])
+   assert_false set.disjoint?(Set[5,6,7])
+   assert_false set.disjoint?(Set[1,2,6,8,4])
+   # Make sure set hasn't changed
+   assert_equal(Set[3,4,5], set)
+ end
+ assert("Set#each") do
+   ary = [1,3,5,7,10,20]
+   set = Set.new(ary)
+   ret = set.each { |o| }
+   assert_true set.equal?(ret) # assert_same
+   e = set.each
+   assert_true e.instance_of?(Enumerator)
+   assert_nothing_raised {
+     set.each { |o|
+       ary.delete(o) or raise "unexpected element: #{o}"
+     }
+     ary.empty? or raise "forgotten elements: #{ary.join(', ')}"
+   }  
+ end
+ assert("Set#add") do
+   set = Set[1,2,3]
+   ret = set.add(2)
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[1,2,3], set)
+   ret = set.add(4)
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[1,2,3,4], set)
+ end
+ assert("Set#add?") do
+   set = Set[1,2,3]
+   ret = set.add?(2)
+   assert_nil ret
+   assert_equal(Set[1,2,3], set)
+   ret = set.add?(4)
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[1,2,3,4], set)
+ end
+ assert("Set#delete") do
+   set = Set[1,2,3]
+   ret = set.delete(4)
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[1,2,3], set)
+   ret = set.delete(2)
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[1,3], set)
+ end
+ assert("Set#delete?") do
+   set = Set[1,2,3]
+   ret = set.delete?(4)
+   assert_nil ret
+   assert_equal(Set[1,2,3], set)
+   ret = set.delete?(1)
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[2,3], set)
+ end
+ assert("Set#delete_if") do
+   set = Set.new(1..10)
+   ret = set.delete_if { |i| i > 10 }
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set.new(1..10), set)
+   set = Set.new(1..10)
+   ret = set.delete_if { |i| i % 3 == 0 }
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[1,2,4,5,7,8,10], set)
+ end
+ assert("Set#keep_if") do
+   set = Set.new(1..10)
+   ret = set.keep_if { |i| i <= 10 }
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set.new(1..10), set)
+   set = Set.new(1..10)
+   ret = set.keep_if { |i| i % 3 != 0 }
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[1,2,4,5,7,8,10], set)
+ end
+ assert("Set#collect!") do
+   set = Set[1,2,3,'a','b','c',-1..1,2..4]
+   ret = set.collect! { |i|
+     case i
+     when Numeric
+       i * 2
+     when String
+       i.upcase
+     else
+       nil
+     end
+   }
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[2,4,6,"A","B","C",nil], set)
+ end
+ assert("Set#reject!") do
+   set = Set.new(1..10)
+   ret = set.reject! { |i| i > 10 }
+   assert_nil(ret)
+   assert_equal(Set.new(1..10), set)
+   ret = set.reject! { |i| i % 3 == 0 }
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[1,2,4,5,7,8,10], set)
+ end
+ # this test is not in CRuby
+ assert("Set#select!") do
+   set = Set.new(1..10)
+   ret = set.select! { |i| i <= 10 }
+   assert_nil(ret)
+   assert_equal(Set.new(1..10), set)
+   ret = set.select! { |i| i % 3 != 0 }
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[1,2,4,5,7,8,10], set)
+ end
+ assert("Set#merge") do
+   set = Set[1,2,3]
+   ret = set.merge([2,4,6])
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[1,2,3,4,6], set)
+ end
+ assert("Set#subtract") do
+   set = Set[1,2,3]
+   ret = set.subtract([2,4,6])
+   assert_true set.equal?(ret) # assert_same
+   assert_equal(Set[1,3], set)
+ end
+ assert("Set#+") do
+   set = Set[1,2,3]
+   ret = set + [2,4,6]
+   assert_false set.equal?(ret) # assert_not_same
+   assert_equal(Set[1,2,3,4,6], ret)
+ end
+ assert("Set#-") do
+   set = Set[1,2,3]
+   ret = set - [2,4,6]
+   assert_false set.equal?(ret) # assert_not_same
+   assert_equal(Set[1,3], ret)  
+ end
+ assert("Set#&") do
+   set = Set[1,2,3,4]
+   ret = set & [2,4,6]
+   assert_false set.equal?(ret) # assert_not_same
+   assert_equal(Set[2,4], ret)  
+ end
+ assert("Set#^") do
+   set = Set[1,2,3,4]
+   ret = set ^ [2,4,5,5]
+   assert_false set.equal?(ret) # assert_not_same
+   assert_equal(Set[1,3,5], ret)  
+ end
+ assert("Set#==") do
+   set1 = Set[2,3,1]
+   set2 = Set[1,2,3]
+   assert_equal(set1, set1)
+   assert_equal(set1, set2)
+   assert_not_equal(Set[1], [1])
+   set1 = Class.new(Set)["a", "b"]
+   set2 = Set["a", "b", set1]
+   set1 = set1.add(set1.clone)
+   assert_equal(set2, set2.clone)
+   assert_equal(set1.clone, set1)
+ end
+ assert("Set#classify") do
+   set = Set.new(1..10)
+   ret = set.classify { |i| i % 3 }
+   assert_equal(3, ret.size)
+   assert_equal(Hash, ret.class)
+   ret.each_value { |v| assert_equal(Set, v.class) }
+   assert_equal(Set[3,6,9], ret[0])
+   assert_equal(Set[1,4,7,10], ret[1])
+   assert_equal(Set[2,5,8], ret[2])
+ end
+ assert("Set#divide") do
+   # arity is 1
+   set = Set.new(1..10)
+   ret = set.divide { |i| i % 3 }
+   assert_equal(3, ret.size)
+   n = 0
+   ret.each { |s| n += s.size }
+   assert_equal(set.size, n)
+   assert_equal(set, ret.flatten)
+   assert_equal(Set, ret.class)
+   assert_true(ret.include?(Set[3,6,9]))
+   assert_true(ret.include?(Set[1,4,7,10]))
+   assert_true(ret.include?(Set[2,5,8]))
+   # arity is 2
+   set = Set[7,10,5,11,1,3,4,9,0]
+   assert_raise(NotImplementedError) {
+     ret = set.divide { |a, b| (a - b).abs == 1 }
+   }
+   # assert_equal(4, ret.size)
+   # n = 0
+   # ret.each { |s| n += s.size }
+   # assert_equal(set.size, n)
+   # assert_equal(set, ret.flatten)
+   # assert_equal(Set, ret.class)
+ end
+ # taint is not implemented yet
+ #assert("taintness") do
+ #  orig = set = Set[1,2,3]
+ #  assert_false set.tainted?
+ #  assert_true set.taint.equal?(orig) # assert_same
+ #  assert_true set.tainted?
+ #  assert_true set.instance_variable_get(:@hash).tainted?
+ #  assert_true set.untaint.equal?(orig) # assert_same
+ #  assert_false set.tainted?
+ #end
+ # freeze is not implemented yet
+ #assert("freeze") do
+ #  orig = set = Set[1,2,3]
+ #  assert_equal false, set.frozen?
+ #  set << 4
+ #  assert_same orig, set.freeze
+ #  assert_equal true, set.frozen?
+ #  assert_raise(RuntimeError) {
+ #    set << 5
+ #  }
+ #  assert_equal 4, set.size
+ #end
+ #  assert("freeze_dup") do
+ #    set1 = Set[1,2,3]
+ #    set1.freeze
+ #    set2 = set1.dup
+ #
+ #    assert_not_predicate set2, :frozen?
+ #    assert_nothing_raised {
+ #      set2.add 4
+ #    }
+ #  end
+ #  assert("reeze_clone") do
+ #    set1 = Set[1,2,3]
+ #    set1.freeze
+ #    set2 = set1.clone
+ #
+ #    assert_predicate set2, :frozen?
+ #    assert_raise(RuntimeError) {
+ #      set2.add 5
+ #    }
+ #  end
+ #
+ assert("Set#inspect") do
+   set = Set[1,2,3]
+   assert_equal("#<Set: {1, 2, 3}>", set.inspect)
+ end