Skip to content

Instantly share code, notes, and snippets.

@jarib
Created February 28, 2011 19:56
Show Gist options
  • Save jarib/847911 to your computer and use it in GitHub Desktop.
Save jarib/847911 to your computer and use it in GitHub Desktop.
java.util.Properties-like class for Ruby
# encoding: utf-8
# Pure-ruby java.util.Properties-like class
class Properties < Hash
REGEXP = %r{
\A\s* # ignore whitespace at BOL
([^\s\#;]+?) # the variable cannot contain spaces or comment characters
\s*=\s* # ignore whitespace around the equal sign
([^\#;]*?) # the value cannot contain comment characters
\s* # ignore whitespace at end of line
(\#|;|\z) # the matching ends if we meet a comment character or EOL
}x
def initialize(defaults = nil)
super()
unless [nil, Hash].any? { |e| e === defaults }
raise TypeError, "defaults must be Properties or Hash"
end
stringify defaults if defaults.instance_of? Hash
@parent = defaults
end
def load(string)
string.split(/\r?\n/).each do |line|
if line =~ REGEXP
self[$1] = $2.strip #.split(',')
end
end
end
def [](key)
if obj = super
obj
elsif @parent
@parent[key]
end
end
def []=(key, value)
key, value = key.to_s, value.to_s
super(key, value)
end
def to_s
@parent ? @parent.merge(self).to_s : super
end
def inspect
@parent ? @parent.merge(self).inspect : super
end
def pretty_print(q)
@parent ? @parent.merge(self).pretty_print(q) : super
end
def each(&blk)
@parent ? @parent.merge(self).each(&blk) : super
end
def values_at(*keys)
keys.map { |key| self[key] }
end
private
def stringify(hash)
r = {}
hash.each do |key, value|
r[key.to_s] = value.to_s
end
hash.replace r
end
end # Properties
# encoding: utf-8
require "#{File.dirname(__FILE__)}/spec_helper"
describe "Properties" do
def new_from_string(str)
p = Properties.new
p.load str
p
end
describe "#load" do
it "should parse a simple Properties string" do
str = <<-PROPERTIES
foo = bar
foo.bar.baz = boo
PROPERTIES
p = new_from_string str
p['foo'].should == 'bar'
p['foo.bar.baz'].should == 'boo'
end
end
it "should parse empty values correctly" do
str = <<-PROPERTIES
foo =
bar = baz
PROPERTIES
p = new_from_string str
p['foo'].should == ''
p['bar'].should == 'baz'
end
describe "#new" do
it "should initialize a new Properties object with the given defaults" do
p = Properties.new('foo' => 'bar', 'boo' => 'baz')
p['foo'].should == 'bar'
p['boo'].should == 'baz'
end
it "should only use the parent if the key doesn't exist in the loaded string" do
p = Properties.new('foo' => 'bar', 'boo' => 'baz')
p.load <<-PROPERTIES
boo = foo
PROPERTIES
p['boo'].should == 'foo'
p['foo'].should == 'bar'
end
it "should stringify keys/values in the parent" do
p = Properties.new(:foo => 'bar')
p['foo'].should == 'bar'
p[:bar].should be_nil
end
it "should stringify keys being set" do
p = Properties.new
p[:foo] = 'bar'
p['foo'].should_not be_nil
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment