On Sat, Apr 3, 2010 at 2:30 PM, Intransition <transfire / gmail.com> wrote: > Here, I worked on it I came up with: Is this the Array#recursively "TODO: Can this be generalized in Enumerable?" :) http://facets.rubyforge.org/apidoc/api/core/classes/Array.html#M000055 Oddly enough, I'd also started wondering about a fully recursive version! Borrowing ideas from Facets (Array#recursively, Enumerable#traverse) I came up with the code at the end of this post. It's not as general as either your code or Robert Klemme's (sort of "orthogonal" to yours) but it was intended to cope with an element of the array having an each method but not mixing in Enumerable > I am going to add this to Facets, but I have to decide for sure on the > name. Which is better? #visit #traverse #recurse other ? I know they are long names, but because it's a recursive each, why not #each_recursively (Facets already uses recursively) or #each_recursive (I prefer the latter - shorter!) and maybe have visit as a short alias? Or maybe use Robert Klemme's #each_flat, although since this will apply a recursive each to Ranges (or Files, or anything else using each which mixes in Enumerable) I'm not sure that flatten (or a derivative) is fully appropriate? I also like Robert Klemme's idea of having a level parameter, so if Robert is agreeable - and from his Ruby-talk posts he seems to be a very agreeable person! - maybe include levels, maybe renamed depth? (I've thought of using level in a more general Find module, and eventually decided depth was a better word for the concept. I can't remember why, but I'm sure there must have been very good reasons!) And maybe cater for "unlimited" depth using depth/levels = nil ? So: if levels > 1 && Enumerable === x x.each_flat(levels - 1, &b) would become if (! levels || levels > 1) && Enumerable === x x.each_flat( levels && levels - 1, &b) A question: should the depth/levels test be levels > 1 or > 0? Using [ 2..2 ] and "levels > 1": levels param: 0 #=> 2..2; 1 #=> 2..2; 2 #=> 2; Using [ 2..2 ] and "levels > 0": levels param: 0 #=> 2..2; 1 #=> 2; 2 #=> 2; It seems (maybe?) more logical to have depth/levels arguments: 0 means don't do any recursive expansion of each; 1 means do some recursive expansion of each; ### Intended to cope with an element of an array (or whatever) ### having an each method but not mixing in Enumerable. module Enumerable def visits(&block) each { |item| Enumerable.visits?(item, &block) } end def Enumerable.visits?(obj, &block) if obj.respond_to?( :each ) then obj.each { |item| Enumerable.visits?(item, &block) } else yield obj end end end