On Thu, 13 Apr 2006, Daniel Berger wrote:

> Just a quick note - precompiling the regular expressions might help here, 
> too.

very good point! :


     harp:~ > cat /usr/share/tcl8.3/*tcl |wc -l
        3533

     harp:~ > time cat /usr/share/tcl8.3/*tcl |ruby a.rb >/dev/null

     real    0m0.848s
     user    0m0.810s
     sys     0m0.020s


this is down from 3 sec!


   harp:~ > cat a.rb

   require 'yaml'
   class TclIndex
     def initialize arg
       @procs, @vars = {}, {}
       parse arg
     end
     def parse a
       read = lambda{|io| io.readlines.map!{|l| l.gsub %r/#.*$/, ''}}
       lines = a.respond_to?('readlines') ? read[a] : open(a){|f|read[f]}
       proc_re = Hash.new{|h,k| h[k] = %r/\b#{ k }\b/}
       var_re = Hash.new{|h,k| h[k] = %r/\b#{ k }\b|\$#{ k }\b/}
       lines.each do |line|
         case line
           when %r/^ \s* proc \s+ (\w+)/iox
             @procs[$1] = -1
           when %r/^ \s* set \s+ (\w+)/iox
             @vars[$1] = 0
         end
         @procs.keys.each{|k| @procs[k] += 1 if line[proc_re[k]]}
         @vars.keys.each{|k| @vars[k] += 1 if line[var_re[k]]}
       end
     end
     def report o
       o << {
         'procs' => @procs.to_a.sort_by{|ab| ab.last}.map{|ab| Hash[*ab]},
         'vars' => @vars.to_a.sort_by{|ab| ab.last}.map{|ab| Hash[*ab]},
       }.to_yaml
     end
   end


   abort "Usage: [inputfilepath = stdin] [outputfilename = stdout]" if
     ARGV.delete('help') or ARGV.delete('--help')

   i = ARGV.shift || STDIN
   o = ARGV.shift || STDOUT

   idx = TclIndex.new i
   idx.report o



regards.

-a
-- 
be kind whenever possible... it is always possible.
- h.h. the 14th dali lama