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:
Rake provides two functions, recursive directory searching
and line by line searching (note that 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.
I almost never use a Ruby installation without Rake installed as
well. So the extra dependency is not a concern to me.
Since I use Rake all the time, the syntax is at my fingertips. I
don’t use Find often enough to use it without checking RI.
The Find version of the script is several times longer than the Rake
version (included below for comparison).
However …
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.
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
Update (31/Aug/06)
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.