The Findmodule supports the top-down traversal of a set of file paths.

For example, to total the size of all files under your home directory, ignoring anything in a “dot” directory (e.g. $HOME/.ssh):

require 'find'

total_size = 0

Find.find(ENV["HOME"]) do |path|
  if FileTest.directory?(path)
    if File.basename(path)[0] == .
      Find.prune       # Don't look any further into this directory.
    else
      next
    end
  else
    total_size += FileTest.size(path)
  end
end
Methods
F
P
Class Public methods
find(*paths)

Calls the associated block with the name of every file and directory listed as arguments, then recursively on their subdirectories, and so on.

See the Findmodule documentation for an example.

# File lib/find.rb, line 35
def find(*paths) # :yield: path
  block_given? or return enum_for(__method__, *paths)

  paths.collect!{|d| raise Errno::ENOENT unless File.exist?(d); d.dup}
  while file = paths.shift
    catch(:prune) do
      yield file.dup.taint
      begin
        s = File.lstat(file)
      rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
        next
      end
      if s.directory? then
        begin
          fs = Dir.entries(file)
        rescue Errno::ENOENT, Errno::EACCES, Errno::ENOTDIR, Errno::ELOOP, Errno::ENAMETOOLONG
          next
        end
        fs.sort!
        fs.reverse_each {|f|
          next if f == "." or f == ".."
          f = File.join(file, f)
          paths.unshift f.untaint
        }
      end
    end
  end
end
prune()

Skips the current file or directory, restarting the loop with the next entry. If the current file is a directory, that directory will not be recursively entered. Meaningful only within the block associated with ::find.

See the Findmodule documentation for an example.

# File lib/find.rb, line 72
def prune
  throw :prune
end