> -----Original Message----- > From: Mathieu Bouchard [mailto:matju / cam.org] [...] > ListMixin #(common to Array and String) > ArrayMixin #(includes ArrayInterface, ListMixin) > ArrayInterface #(the basic operations that are left to implement) > ArrayInterfaceSafe #(assertion-checked version of the preceding) > CommonAssert #(used by ArrayInterfaceSafe, StringInterfaceSafe) > ArrayUsingArray #(dummy impl of ArrayInterfaceSafe, includes ArrayMixin) > > As you see, methods are not divided according to individual purposes but > according to a larger scheme of small interface vs large interface / > interface vs implementation vs verification / shared with string vs > specific to array. > > The "set operations" in Array are somewhat more restrictive than set > operations. See [ruby-talk:6756], [ruby-talk:6723]. Order of elements is > important (repeating elements do collapse, however). I remember this discussion. The problem with set operations is that they really are somewhat arbitrary (ultimately indicator Hash functions are a better way of implementing sets IMHO) due to the fact that there is no natural way to order elements/objects (besides ``elements.id'' but this depends on the context) and the built-in set operations are modeled around the set theoretic interpretation - a multi set interpretation is just as sensible. Also self-referential Arrays - try to run ruby -e 'x = [1]; x << y = ["a"]; y << [x]; x & x' - are the enemies of the set theoretic interpretation. Because of this a ArrayMixin writer might not want to provide any set-theoretic facilities at all (see below). > I don't see the usefulness of putting lists/queues/stacks/sets > functionalities in different modules (that i'll have to include into > ArrayMixin to respect the builtin Array protocol) if there is nowhere they > can be reused. > > The "set operations" could be somewhat reusable in another context (though > they could be optimized out of their restrictions in those contexts, and > #uniq would become irrelevant, etc). > > May I know what you have in mind in a detailed fashion? Actually the main motivation behind organizing lists/queues/stacks/sets functionality into modules would be that you could choose NOT to include all of these functionalities - i.e. it would be nice if you could write ListMixin/QuesesMixin ... 's which would be functional on their own but provide the full Array facilities when included into a single Module. [...] > The builtin semantics follow my implementation. > > Or rather: > > My implementation follows the builtin semantics. > > It's just that when you try to #flatten! an array that immediately > contains self-references, it skips them as a special case (i don't know > why Array#flatten! does this). However when you do #flatten, a dup is The built-in #flatten! does not throw exceptions on more complicated examples like $ ruby -e 'x = [1]; x << y = ["a"]; y << [x]; x.flatten!; p x' [1, "a"] either, it simply throws out a self-referential entry if it encounters it a second time - kind of fun if you #flatten! in a threading environment. > performed first, then #flatten! is called on the copy, and so the > base-level self-references are not base-level anymore, and #flatten! > explodes. > Christoph