Hello,
I seem to be having some difficulty creating a version of python's os.walk() for ruby, and I was hoping for some pointers.
As some background, python's os.walk() [1] is a generator function. It is passed the top of a directory tree and it returns the following for each subdirectory that it encounters:
. the working directory
. an Array of subdirectories
. an Array of non-directory files
Here is some truncated output for my use case:
>>> import os
>>> repo = '/usr/local/nfsen/profiles-data/live/lax1er1'
>>> for root, dirs, files in os.walk(repo):
... if len(files) == 288:
... print root
...
/usr/local/nfsen/profiles-data/live/lax1er1/2008/11/11
..
/usr/local/nfsen/profiles-data/live/lax1er1/2008/12/13
Essentially, when there are exactly 288 files in a subdirectory, I want to print or otherwise do something with the working directory.
Here is my attempt at simply translating this library function to ruby:
#! /usr/bin/env ruby
require 'pp'
dirs = [ '/usr/local/nfsen/profiles-data/live/lax1er1' ]
def find_dirs(top)
dirs = []
nondirs = []
Dir.entries(top).each do |f|
next if f =~ /(\.$|\.\.$)/
full_path = [top, f].join('/')
if File.directory?(full_path)
dirs.push(full_path)
else
nondirs.push(full_path)
end
end
yield top, dirs, nondirs
dirs.each do |d|
if File.directory?(d)
for o in find_dirs(d) { |a,b,c| puts "#{a} #{b} #{c}"}
yield o
end
end
end
end
find_dirs(dirs[0]) do |top,dirs,nondirs|
if nondirs.length == 288
puts "#{top}"
end
end
There are some things that I know are wrong or missing, but that is due to trying to get something to run at all without throwing an exception.
The part that I think is totally wrong is:
for o in find_dirs(d) { |a,b,c| puts "#{a} #{b} #{c}"}
It's really only in there currently to keep the from getting 'LocalJumpError: no block given.' Unfortunately, I have no idea what the correct way to deal with this would be.
The missing part would be including the directory contents in addition to the working directory and the Array of subdirectories.
So, I guess my main questions would be: What do I need to do to get this sort of a generator to work? Do I need to wrap this up in a 'class' or is a 'def' sufficient? What should the block look like, and where should it be in the code?
Thanks for reading,
Brad
[1] http://svn.python.org/view/python/branches/release25-maint/Lib/os.py?rev=62757&view=auto