The majority of the scripts I write make heavy use of the find module. Today it took me about two hours to debug one of them. It was a regex issue, and the wrappers I built around find weren’t that well thought out. Later today, I wrote this :
module FindTools
extend self
def find_matching(hash)
where = hash[:where] || "."
conditions = hash[:conditions] || []
select_callback = hash[:select_callback] || lambda {|f|}
all_files_callback = hash[:all_files_callback] || lambda {|f|}
files = []
matches = false
Find.find(where) do |file|
all_files_callback.call(file)
matches = true
select_file = true
conditions.each do |condition|
res = condition.call(file)
matches = false if !res
end
if matches
select_callback.call(file)
files << file
end
end
return files
end
end
and you can use it like this:
files = FindTools.find_matching(
:where => ARGV[0],
:conditions => [
lambda {|file| File.directory?(file)},
lambda {|file| file !~ /thunder|firefox|chrome/i}
],
)
You can chain an unlimited number of lambdas/procs here, the only prerequisite is that the callback has a call method. You can add two more callbacks here :
files = FindTools.find_matching(
:where => ARGV[0],
:conditions => [
lambda {|file| File.directory?(file)},
lambda {|file| file =~/\d+/i},
lambda {|file| file !~ /flash|google/i},
lambda {|file| file !~ /cygwin|wing|temp/i},
lambda {|file| file !~ /thunder|firefox|chrome/i}
],
:select_callback => lambda {|f| puts f}
)
The select_callback fires every time a file passes all conditions. You can also use the all_files_callback like this:
files = FindTools.find_matching(
:where => ARGV[0],
:conditions => [
lambda {|file| File.directory?(file)},
lambda {|file| file =~/\d+/i},
lambda {|file| file !~ /flash|google/i},
lambda {|file| file !~ /cygwin|wing|temp/i},
lambda {|file| file !~ /thunder|firefox|chrome/i}
],
:all_files_callback => lambda {|f| puts f}
)
and this will fire on all files found by find, no matter if they passed the conditions or not.
I know this is the Nth post you read about finding stuff here, but, what can I say? I find this to be the most important task when automating stuff.
