peer review request - selective dir search and file loader.

B

Bill Guindon

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
 
B

Bill Guindon

Probably should have warned that it was a bit long.

Probably should have included a sample call:
@filters = [/\/ldc_[^\/]*/, /\.html$/]
@src = Source.new( "source/", @filters, false)
src.load

btw... filters are applied in order supplied.

I'll get the hang of this sooner or later.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,156
Messages
2,570,878
Members
47,413
Latest member
KeiraLight

Latest Threads

Top