From: Markus Date: 2005-05-24T21:28:29+09:00 Subject: Re: Array.=== in Rails Bug On Mon, 2005-05-23 at 21:47, Jim Weirich wrote: > FileList in Rake used to inherit from Array to get array-like behavior. I > recently changed it to delegate to an internally held array. I found that > the delegation allowed a FileList to be used in more places where an Array > was expected ... mainly because some methods check for the to_ary method to > see if an object should be treated like an array. This is a much more thorough wrapping (see earlier on this thread). It fools everything (x.class, x.is_a?, etc.) but does not fool Class#===, which produces incorrect behaviour. If you are going to produce something that walks like a duck, by all means use a delegater; if you want something to _be_ a duck, you need to make sure that Duck#=== accepts it as one. > Given the following code: > > [FileList['a', 'b'], FileList['c', 'd']].flatten > > Rake 0.5.0 which inherits from Array will return: [] > Rake 0.5.3 which delegates to Array will return: ['a', 'b', 'c', 'd'] > > That's because flatten accesses the array elements directly. Since FileList > is lazy loaded, bypassing the methods means that the elements are never > loaded. By switching to a delegation method, flatten checks for :to_ary, > which can be used to trigger loading and make everyone happy. In this case. _all_ the methods are delegated, so it should work correctly. > Short version: Inheriting from Array is not always the most compatible. > > Another moral to the story: If you want to check for something that is array > like (but doesn't have to be an array), check to see if it responds to > to_ary. Agreed. Here though, you could do all the checking you wanted and still get caught out. If the _only_ way to distinguish a surrogate from it's intended class is a bug in the impersonation, it is a bug. This is not to say that they might have gotten away with something Array like, just that if they are going to return true for x.is_a?(Array), and return Array for x.class, then Array === x should return true as well. --MarkusQ