class CsvReader::ParserFixed
Private Class Methods
build_logger()
click to toggle source
add simple logger with debug flag/switch
use Parser.debug = true # to turn on
todo/fix: use logutils instead of std logger - why? why not?
# File lib/csvreader/parser_fixed.rb, line 14 def self.build_logger() l = Logger.new( STDOUT ) l.level = :info ## set to :info on start; note: is 0 (debug) by default l end
logger()
click to toggle source
# File lib/csvreader/parser_fixed.rb, line 19 def self.logger() @@logger ||= build_logger; end
Private Instance Methods
logger()
click to toggle source
# File lib/csvreader/parser_fixed.rb, line 20 def logger() self.class.logger; end
parse( data, width:, &block )
click to toggle source
# File lib/csvreader/parser_fixed.rb, line 23 def parse( data, width:, &block ) ## note: input: required each_line (string or io/file for example) input = data ## assume it's a string or io/file handle if block_given? parse_lines( input, width: width, &block ) else records = [] parse_lines( input, width: width ) do |record| records << record end records end end
parse_lines( input, width:, &block )
click to toggle source
# File lib/csvreader/parser_fixed.rb, line 46 def parse_lines( input, width:, &block ) ## note: each line only works with \n (windows) or \r\n (unix) ## will NOT work with \r (old mac, any others?) only!!!! input.each_line do |line| ## note: chomp('') if is an empty string, ## it will remove all trailing newlines from the string. ## use line.sub(/[\n\r]*$/, '') or similar instead - why? why not? line = line.chomp( '' ) logger.debug "line:" if logger.debug? logger.debug line.pretty_inspect if logger.debug? ## skip empty lines and comments if line =~ /^[ \t]*$/ ## skip blank lines (with whitespace only) logger.debug "skip blank line" if logger.debug? next end if line =~ /^[ \t]*#/ # start_with?( "#" ) -- skip comment lines (note: allow leading whitespaces) logger.debug "skip comment line" if logger.debug? next end if width.is_a?( String ) ## assume it's String#unpack format e.g. ## "209231-231992395 MoreData".unpack('aa5A1A9a4Z*') ## returns an array as follows : ## ["2", "09231", "-", "231992395", " ", "MoreData"] ## see String#unpack values = line.unpack( width ) else ## assume array with integers values = [] offset = 0 # start position / offset width.each_with_index do |w,i| logger.debug "[#{i}] start: #{offset}, width: #{w}" if logger.debug? if w < 0 ## convention - if width negative, skip column # note: minus (-) and minus (-) equal plus (+) ## e.g. 2 - -2 = 4 offset -= w else value = line[offset, w] value = value.strip if value ## note: if not nil strip; only use rstrip (for trailing only) - why? why not? values << value offset += w end end end ## note: requires block - enforce? how? why? why not? block.call( values ) end end