From: Thomas Date: 2005-05-23T00:37:40+09:00 Subject: Uniform vector class, inheriting from Array: How to make sure that methods return a Vector and not an Array? 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