From: timr Date: 2010-11-01T07:30:15+09:00 Subject: the dark side of inherited methods Let's say I want to make a new class, Vector (that will function, eventually, like R vectors for mathematical operations), and I write this: class Vector < Array def initialize(*arr) super(arr.flatten) end end v = Vector.new(1,2,3) # => [1, 2, 3] v.class # => Vector v.collect{|item| item * 3}.class # => Array v.collect!{|item| item * 3}.class # => Vector I noticed that I inherited the Array#collect and Array#collect! methods. Yeah for inheritance! But then look at the returned classes. Array#collect returns and array. Array.collect! returns a Vector. If you look at the underlying C code that defines these methods the response makes sense. Collect! alters the object itself using the results from the block, while collect builds a new Array from the results of the block. But geesh, that means to have consistent behavior, I have to add the following (and worse, look through every other Array method to determine if the return value should be a vector rather than an array): class Vector < Array def collect(&blk) Vector.new(super) #gets the return from super and puts that back into a vector object end end v = Vector.new(1,2,3) # => [1, 2, 3] v.class # => Vector v.collect{|item| item * 3}.class # => Vector v.collect!{|item| item * 3}.class # => Vector When a method has the form of array -> an_array I want it to take a vector -> a_vector, but I get vector -> array. Is there a simple way to fix this for all similar methods? Or do I just have to live with the dark side of inherited methods? Thanks, Tim