Hi folks,

I recently tried to implement a uniform vector class being defined as a 
vector the elements of which all comply to some kind of common interface 
or are a subclass of some prototype class.

My first naive approach was to inherit from Array and to overwrite some 
methods to make sure that new elements are ok. This works fine for 
methods like []=, <<, or unshift but when implementing + I ran into the 
following problem: Array#+ returns an Array and not a Vector which is 
why I have to create a new Vector from the result of Array#+. As Array#+ 
already creates a new Array, this probably isn't very efficient and I 
don't like the idea of having to do this for all possible methods that 
return an Array. I was hoping to be able to somehow limit my 
modifications of Array to a few essential methods.

So, the question is: Does somebody know a way to make sure that methods 
returning an Array (+, &, -, * etc.) always return a Vector without 
having to redefine each of them?

Please find my current toy implementation down below.

Cheers,
Thomas.


class Vector < Array
    def []=(pos, val)
        check_values([val])
        super
    end

    def +(values)
        check_values(values)
        Vector.new(super)
    end
   
    def <<(*values)
        check_values(values)
        super
    end
  
    def unshift(*values)
        check_values(values)
        super
    end
   
    def check_values(values)
        unless defined?(@protoclass)
            prototype = self[0] || values[0]
            @protoclass = prototype.class
        end
        values.each do |e|
            unless e.kind_of?(@protoclass)
                raise TypeError, "Expected #{@protoclass} but got 
#{e.class}", caller[2..-1]
            end
        end
    end
end

if __FILE__ == $0
    v = Vector.new
    # these are okay
    v << 1
    v[2] = 2
    p v + [1,2,3]
    v += [1,2,3]
    v.unshift(3)

    # but this should throw an error (that's what this is all about)
    v << "a"
end