M
Martin Hansen
Hello there,
I am struggling to get a grip on OO (and Ruby) and write a parser for
this particular data format described at the below get_record method.
The goal is to parse and emit records of this type and be able to
manipulate these with the methods in class Hash.
For now I am trying to get parsing to work, and the problem here is,
that the add methods is not defined for Hash. What is the best way of
doing that?
M
class Record < Hash
SEPERATOR = "\n---\n"
def initialize(path=nil)
@path = path
@ios = File.open(@path, 'r') if @path
end
# Reads the next 'record' from the I/O stream. The records are
separated by
# lines of "---" and each record consists of a varying number of lines
with a
# key/value pair separated by ": ". The record is returned as a hash.
def get_record
block = @ios.gets(SEPERATOR).chomp!(SEPERATOR)
record = {}
block.each_line do |line|
fields = line.split(": ")
raise ArgumentError, "Bad record line: #{line}" if fields.length
!= 2
record.add(fields[0],fields[1])
end
record
end
# Add a key value pair to this record.
def add(key, value)
raise ArgumentError, "Bad key contains ': ' or '\n' ->#{key}" if
key.match(": |\n")
raise ArgumentError, "Bad value contains ': ' or '\n' ->#{value}" if
value.match(": |\n")
self[key] = value
end
# Return the content of this record as a string.
def to_s
return nil if empty?
self.map { | key, val | "#{ key }: #{ val }" }.join( "\n" ) +
SEPERATOR
end
end
I am struggling to get a grip on OO (and Ruby) and write a parser for
this particular data format described at the below get_record method.
The goal is to parse and emit records of this type and be able to
manipulate these with the methods in class Hash.
For now I am trying to get parsing to work, and the problem here is,
that the add methods is not defined for Hash. What is the best way of
doing that?
M
class Record < Hash
SEPERATOR = "\n---\n"
def initialize(path=nil)
@path = path
@ios = File.open(@path, 'r') if @path
end
# Reads the next 'record' from the I/O stream. The records are
separated by
# lines of "---" and each record consists of a varying number of lines
with a
# key/value pair separated by ": ". The record is returned as a hash.
def get_record
block = @ios.gets(SEPERATOR).chomp!(SEPERATOR)
record = {}
block.each_line do |line|
fields = line.split(": ")
raise ArgumentError, "Bad record line: #{line}" if fields.length
!= 2
record.add(fields[0],fields[1])
end
record
end
# Add a key value pair to this record.
def add(key, value)
raise ArgumentError, "Bad key contains ': ' or '\n' ->#{key}" if
key.match(": |\n")
raise ArgumentError, "Bad value contains ': ' or '\n' ->#{value}" if
value.match(": |\n")
self[key] = value
end
# Return the content of this record as a string.
def to_s
return nil if empty?
self.map { | key, val | "#{ key }: #{ val }" }.join( "\n" ) +
SEPERATOR
end
end