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, ath, arse
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
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, ath, arse
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