This is a follow up to question. I fixed the issues mentioned in the answer as far as my understanding. The union and intersection now return new object instances with new implementation. I also wrote a test, which is below.class MultiSet  include Enumerable  def initialize enum=[]    @members = {}    raise ArgumentError, enum must include the 'Enumerable' module unless enum.kind_of? Enumerable    enum.each do |item|      add item    end  end  def each &blk    @members.each &blk  end  def == other    @members.to_h == other.to_h  end  def eql? other    self == other  end  def members    @members.dup  end    def to_a    a = []    @members.each do |key, count|      count.times { a << key }    end      a  end    def to_set    Set.new members.keys  end  def remove item    if include? item      @members[item] = @members[item] - 1      @members.delete item if @members[item] < 1    end    self  end  def add item    if include? item      @members[item] += 1    else      @members[item] = 1    end    self  end  def clear    @members.clear  end  def multiplicity item    include?(item) ? @members[item] : 0  end  def include? item    @members.include? item  end  def cardinality    @members.values.reduce(0,:+)  end  def | other    union = self.class.new(self.to_a)    other.each do |key, count|      count.times { union.add key }    end    union  end  def & other    intersection = self.class.new    @members.each do |key, count|      if other.include? key        max_count = [count, other.multiplicity(key)].min        max_count.times { intersection.add key }      end      end    intersection  end  alias_method :to_h, :membersendThe testrequire 'minitest/autorun'require_relative 'multiset'require 'set'class MultiSetTest < MiniTest::Unit::TestCase  def test_equal    assert_equal MultiSet.new([1, 3]), MultiSet.new([3, 1])  end  def test_no_duplicates    assert_equal MultiSet.new([1, 1]).to_set, Set.new([1])  end    def test_remove    assert_equal MultiSet.new([1,3]), MultiSet.new([3,2,1]).remove(2)    assert_equal MultiSet.new([1,2,3]), MultiSet.new([3,2,1]).remove(4)    assert_equal MultiSet.new([1,2,3]), MultiSet.new([3,2,1]).remove(2.0)    assert_equal MultiSet.new([1,3]), MultiSet.new([3,2.0,1]).remove(2.0)  end  def test_empty    assert_equal MultiSet.new, MultiSet.new([1,2]).clear    assert_equal MultiSet.new, MultiSet.new.clear  end  def test_multiplicity    assert_equal 2,MultiSet.new([1, 1, 2]).multiplicity(1)    assert_equal 0,MultiSet.new([1, 1, 2]).multiplicity(4)    assert_equal 0,MultiSet.new([1, 1, 2]).multiplicity(1.0)    assert_equal 1,MultiSet.new([1, 1, 2]).multiplicity(2)  end  def test_membership    assert MultiSet.new([1,2,3]).include?(2)    assert MultiSet.new(1..3).include?(2)    refute MultiSet.new(1..3).include?(2.0)    refute MultiSet.new(1..3).include?(4)  end  def test_add    assert_equal MultiSet.new([1,2,3,4]),      MultiSet.new([1,2,4]).add(3)    expected = {1 => 1, 2 =>1, 3 => 2}    assert_equal expected, MultiSet.new([1,2,3]).add(3).to_h    assert_equal MultiSet.new([1,2,3,3.0]),      MultiSet.new([1,2,3]).add(3.0)  end  def test_to_set    assert_equal Set.new, MultiSet.new.to_set    assert_equal Set.new([1,2,3]), MultiSet.new([3,1,2]).to_set  end  def test_cardinality    assert_equal 3,MultiSet.new([1, 1, 2]).cardinality    assert_equal 0,MultiSet.new.cardinality  end  def test_union    assert_equal MultiSet.new([3.0,3,2,1]), MultiSet.new([1,3]) | (MultiSet.new([2,3.0]))    assert_equal MultiSet.new([3,1]), MultiSet.new([1,3]) | (MultiSet.new)    assert_equal MultiSet.new([2]), MultiSet.new([2]) | (MultiSet.new)    assert_equal MultiSet.new([]), MultiSet.new | (MultiSet.new)  end  def test_intersection    assert_equal MultiSet.new([1,1]), MultiSet.new([1,1,1,3]) & (MultiSet.new([1,1,2]))    assert_equal MultiSet.new([3,1]), MultiSet.new([1,3]) | (MultiSet.new)    assert_equal MultiSet.new([2]), MultiSet.new([2]) | (MultiSet.new)    assert_equal MultiSet.new([]), MultiSet.new | (MultiSet.new)  endend
Multiset implementation in Ruby -Take 2
ruby;set