Why Not Find?
After posting FindInCode, someone legitimately asks: “Why not just use Find?”
Good question! Find is a Ruby supplied module to recursively search directories. So why not use it instead of Rake. Then your script won’t have a dependency on Rake.
Well, in short:
egrep is a FileList
method provided by Rake, and is not the same as the grep method
provide by Ruby arrays). Find only handles the directory search
thing.The find version has one advantage over the Rake version in that it does not need to pull in the entire list of files into memory at once. That may be important to you.
Here’s the original version again:
require 'rake' FileList["**/*.rb"].egrep(Regexp.new(ARGV.first))
And here is the Find version:
require 'find'
RE = Regexp.new(ARGV[0])
Find.find('.') do |fn|
next if fn =~ /(^(\.svn|CVS)$)/
next unless fn =~ /\.rb$/
open(fn) do |file|
lines = 0
file.each do |line|
lines += 1
puts "#{fn}:#{lines}:#{line}" if line =~ RE
end
end
end
James Edward Grey II points out that my find example could use a
little makeover. First, the regex that causes .svn
directories to be skipped is incorrect, it only skips the actual
directory, not the contents of the directory. Removing the ”$” from
the match will fix that, but he provides a better solution. Replace
that entire line with:
Find.prune if fn =~ /(^(\.svn|CVS)$)/
I totally forgot about prune.
A minor correction is the use of the lines counter. He
suggests either using each_with_index (I should have
thought of that), or better yet, use file.lineno.
Thanks James!