Hal,

The following is a performance test (using profile.rb and Linux' 'time') of...

My implementation:

--snip--
require 'profile'
def getdirs root
	Dir["#{root}/**/*"].select{ |file| test ?d, file and not test ?l, file  }
end
getdirs '/home/iusris/devel'
--snip--

which uses the recursive ** Dir glob (of Zsh fame).

And the modified implementation suggested earlier (with a symlink-killer and a 
single flatten):

--snip--
require 'profile'
SEP = '/'
def getdirs(root)
    return [] if test ?l, root
    dirs = Dir.entries(root) - [".", ".."]
    temp = dirs.map {|d| root+SEP+d}.select {|d| test(?d,d)}
    temp + temp.map {|x| getdirs(x) }
end
getdirs('/home/iusris/devel').flatten
--snip--

with the following results:

[MINE]:

iusris@codedbliss[~/ruby/sandbox] time ruby getdirs.rb
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 40.84     1.07      1.07        1  1070.00  1500.00  Array#select
 30.53     1.87      0.80        1   800.00  1110.00  Dir#[]
 16.41     2.30      0.43     1230     0.35     0.35  Kernel.test
 11.83     2.61      0.31     1089     0.28     0.28  String#allocate
  0.00     2.61      0.00        1     0.00     0.00  Module#method_added
  0.00     2.61      0.00        1     0.00  2610.00  Object#getdirs
  0.00     2.61      0.00        1     0.00  2620.00  #toplevel
  0.00     2.61      0.00        2     0.00     0.00  Array#allocate

ruby getdirs.rb  2.82s user 0.53s system 648% cpu 0.516 total

[PREVIOUSLY SUGGESTED]:

iusris@codedbliss[~/ruby/sandbox] time ruby getdirs2.rb
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 33.71     9.53      9.53      147    64.83   104.83  Array#-
 20.55    15.34      5.81    13834     0.42     0.42  String#==
  9.44    18.01      2.67      294     9.08   388.50  Array#map
  9.20    20.61      2.60     2230     1.17     1.64  String#+
  6.69    22.50      1.89     3935     0.48     0.48  String#allocate
  4.60    23.80      1.30      147     8.84   922.52  Object#getdirs
  4.03    24.94      1.14      147     7.76    12.79  Dir#each
  3.93    26.05      1.11      147     7.55    12.11  Array#select
  2.51    26.76      0.71     1262     0.56     0.56  Kernel.test
  2.19    27.38      0.62     1031     0.60     0.60  Array#allocate
  0.88    27.63      0.25      147     1.70    16.19  Dir#entries
  0.64    27.81      0.18      411     0.44     0.44  Fixnum#==
  0.60    27.98      0.17        1   170.00   350.00  Array#flatten
  0.50    28.12      0.14      147     0.95     1.36  Array#+
  0.42    28.24      0.12      147     0.82    14.29  Enumerable.to_a
  0.11    28.27      0.03      147     0.20     0.20  Dir#open
  0.00    28.27      0.00        1     0.00 28270.00  #toplevel
  0.00    28.27      0.00        1     0.00     0.00  Module#method_added

ruby getdirs2.rb  28.51s user 0.39s system 373% cpu 7.734 total

As you can see, the previously suggested version takes about 10x longer to 
complete.

--

I call this technique "Glob-orific and Short-tacular"

~ Bruce

-- 
_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ 
  Bruce Williams               http://www.codedbliss.com
  iusris/#ruby-lang            bruce / codedbliss.com
_/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/