From: Bill Guindon Date: 2004-09-02T10:08:35+09:00 Subject: peer review request - selective dir search and file loader. This is the first half of a parser I'm working on. I want it to be fairly intelligent and flexible... when given a file, it should find it, and open it. when given a directory, it should find all files, and read them. when given nothing, it should read DATA if it's available. you can set multiple regex filters to narrow down the file list, and there's a recurse flag. I want it to keep the complete list, because in the end, I want to have the option to copy all files to a new location whether I parse them or not. all comments welcome, but try to be constructive. it's my 1st public lump of Ruby, so it's not likely to be very polished ;) require 'find' require 'fileutils' puts "========================================================================" ############################################################################### class Source attr_reader :filespec, :files attr_accessor :recurse, :filters def initialize(filespec, filters=[], recurse=false) # why even try to build it unless it's what I expected? @path = validate(filespec) # ok, looks kosher, let's give it a shot. @filespec = filespec @filters = filters @recurse = recurse @files = [] end def validate(filespec) case filespec when File, Dir return filespec.path when String, NilClass return filespec.to_s else raise ArgumentError, "I expected a path (String), a File (Obj), a Dir (Obj), or Nil (for DATA). So now... I wonder what you expected me to do with this #{@filespec.class}" end end private :validate def load # preloader if FileTest.directory?(@path) # a Dir, or a String that points to one. Find.find(@path) do |path| if path != @path Find.prune if path == "." or path == ".." Find.prune if not @recurse and FileTest.directory?(path) end @files.push(SourceFile.new(path)) if FileTest.file?(path) end else # it's a file, a string that points to a file (maybe), or nothing. @files.push(SourceFile.new(@filespec)) end # tell files to filter and load themselves # the filters trip the parse switch, and # determine wether the file does a read. @files.each do |file| file.load(@filters) end end end ############################################################################### class SourceFile attr_reader :filespec, :file, :path, :parse attr_accessor :lines alias parse? parse def initialize(filespec=nil, parse=true) # why even try to build it unless it's what I expected? @path = validate(filespec) @filespec = filespec @parse = parse @file = nil @lines = [] end def validate(filespec) case filespec when File return File.path when String if FileTest.file?(filespec) return filespec.gsub(/\/$/,'') else raise ArgumentError, "Could not find source file: #{filespec}" end when NilClass if Object.const_defined?("DATA") return $0 else raise ArgumentError, "No source supplied, and no DATA available." end else raise ArgumentError, "Expected a File or a path (String). You gave me a(n) #{@filespec.class}" end end def load(filters) filters.each do |filter| @parse = (@parse and filter.match(@path)) break if not @parse end if @parse puts "loading " + @path case @filespec when File @file = @filespec when String @file = File.new(@path) when NilClass @file = DATA end @lines = @file.readlines @file.close end end end -- Bill Guindon (aka aGorilla)