On Wednesday 24 September 2008 15:45:13 Kyle Schmitt wrote: > I'm wondering what the _right_ way is to go about getting the right > class with inheritance and super() Maybe it's just me, but I often use encapsulation, instead. > The issue is that while << works fine, the results from + and - return > an Array, not a FixedSizeArray, UNLESS I run the returned value > through a FixedSizeArray.new(), and somehow, that just seems wrong and > wasteful. I would guess it's a result of C code making assumptions (Array is Core stuff, after all, so a lot of C) -- maybe something doing the equivalent of Array.new, rather than self.class.new. With an encapsulated pattern, though, you'd at least be avoiding a new Array object each time: class FixedSizeArray def initialize(size=1,fill=nil) # Old duck-typing habit: kind_of, not is_a if size.kind_of? Array @array = size # Not duplicated -- careful. else @array = Array.new(size, fill) end # Why return self here? FixedSizeArray.new will always # return the new object. Return value here is ignored. end def size=(newsize) # No need to check length==newsize, really if @array.length > newsize @array.slice!(Range.new(0,length-newsize-1)) elsif @array.length < newsize @array.unshift(*Array.new(newsize-length){0}) end size end def <<(data) @array.shift @array << data self end def -(data) self.class.new((@array - data).unshift(*Array.new(size-super(data).length,nil))) end def +(data) # No need for Range; slice will take two arguments self.class.new((@array + data).slice(data.length,@array.size+data.length)) end # Add some array-ness include Enumerable def each *args, &block @array.each *args, &block end end I have no idea which will be more efficient, though. Also, does this graphing tool need to be fast? If not -- if I understand what you're trying to do -- you might consider simply shrinking it down to size (with a single slice call) when you need it. One line is a lot easier to write than a whole class.