Skip to content

Instantly share code, notes, and snippets.

@wogsland
Created May 13, 2014 17:10
Show Gist options
  • Save wogsland/8525ff9e767210069e81 to your computer and use it in GitHub Desktop.
Save wogsland/8525ff9e767210069e81 to your computer and use it in GitHub Desktop.
class RubyParser
#Creates a hash table as the parser object given a file name.
def initialize(filename)
#open the file
@filename = filename
toparse = File.open(@filename,"r")
#build the hash table
@sections = Hash.new
section = ""
key = ""
value = ""
toparse.each_line {|thisline|
if thisline.start_with?("[")
# brackets denote a section, so they'll be the highest level of our hash table
section = thisline.sub("[","")
section = section.sub("]","")
section = section.strip
@sections[section.dup] = Hash.new
else
# first we need to deal with the fact that the value part of key : value pairs can run over multiple lines
has_key = thisline.match(":")
if has_key.nil?
value = @sections[section.dup][key.dup]
@sections[section.dup][key.dup][value.dup] = @sections[section.dup][key.dup][value.dup] + " " + thisline.strip
else
# this line has a key, so we'll add it to our hashtable
parts = thisline.partition(":")
key = parts[0]
key = key.strip
value = parts[2]
value = value.strip
details = Hash[key.dup,value.dup]
if key != ""
@sections[section.dup]= @sections[section.dup].merge(details.dup)
end
end
end
}
toparse.close
rescue Exception => e
puts "error running #{__method__} : " + e.message
end
# Get a string value associated with a given section and key names.
def get_string_value(section,key)
if @sections.has_key?(section) && @sections[section].has_key?(key)
value = String.try_convert(@sections[section][key])
else
value = nil
end
return value
rescue Exception => e
puts "error running #{__method__} : " + e.message
end
# Get an integer value associated with a given section and key names.
def get_integer_value(section,key)
if @sections.has_key?(section) && @sections[section].has_key?(key)
value = @sections[section][key].to_i
else
value = nil
end
return value
rescue Exception => e
puts "error running #{__method__} : " + e.message
end
# Get a floating point value associated with a given section and key names.
def get_float_value(section,key)
if @sections.has_key?(section) && @sections[section].has_key?(key)
value = @sections[section][key].to_f
else
value = nil
end
return value
rescue Exception => e
puts "error running #{__method__} : " + e.message
end
#Writes the information stored in @sections to a new file
def write_to_file(newfile)
to_write = File.open(newfile,"w")
@sections.each{|section,key_values|
to_write.write("[#{section}]\r\n")
@sections[section].each{|key,value|
to_write.write("#{key}:#{value}\r\n")
}
}
to_write.close
rescue Exception => e
puts "error running #{__method__} : " + e.message
end
#Sets a value (regardless of type) for a given section and key names
def set_value(section,key,value)
unless @sections.has_key?(section)
@sections[section] = Hash.new
end
@sections[section][key] = value
rescue Exception => e
puts "error running #{__method__} : " + e.message
end
# Set a string value for a given section and key names, writing the new file to disk.
def set_string_value(section,key,value,filename)
value = String.try_convert(value)
set_value(section,key,value)
write_to_file(filename)
rescue Exception => e
puts "error running #{__method__} : " + e.message
end
# Set an integer value for a given section and key names, writing the new file to disk.
def set_integer_value(section,key,value,filename)
value = value.to_i
set_value(section,key,value)
write_to_file(filename)
rescue Exception => e
puts "error running #{__method__} : " + e.message
end
# Set a floating point value for a given section and key names, writing the new file to disk.
def set_float_value(section,key,value,filename)
value = value.to_f
set_value(section,key,value)
write_to_file(filename)
rescue Exception => e
puts "error running #{__method__} : " + e.message
end
end
# testing functionality
puts "Testing creation of a hash table as the parser object given a file name.\n"
rp = RubyParser.new("testfile.txt")
puts rp.instance_variable_get(:@filename)
puts rp.instance_variable_get(:@sections)
puts "\n"
puts "Getting a string value associated with a given section and key names.\n"
puts rp.get_string_value("trailer","budget")
puts "\n"
puts "Getting integer values associated with a given section and key names.\n"
puts rp.get_integer_value("header","budget")
puts rp.get_integer_value("trailer","budget")
puts "\n"
puts "Getting float values associated with a given section and key names.\n"
puts rp.get_float_value("header","budget")
puts rp.get_float_value("header","accessed")
puts rp.get_float_value("trailer","budget")
puts "\n"
puts "Testing helper functions.\n"
rp.write_to_file("test_one.txt")
rp.set_value("trailer","director","BJW")
puts rp.instance_variable_get(:@sections)
puts "\n"
puts "Testing setting string, integer and floating point values for a given section and name, writing the new file to disc.\n"
rp.set_string_value("trailer","key grip","that guy","test_two.txt")
rp.set_integer_value("trailer","cost",3.14,"test_three.txt")
rp.set_float_value("trailer","gaffer",3.14,"test_four.txt")
[header]
project: Programming Test
budget : 4.5
accessed :205
[meta data]
description : This is a tediously long description of the Lonely Planet
programming test that you are taking. Tedious isn't the right word, but
it's the first word that comes to mind.
correction text: I meant 'moderately,' not 'tediously,' above.
[ trailer ]
budget:all out of budget.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment