=begin header
Simple scheme for properties
$Author: Hiroshi IGARASHI <igarashi@ueda.info.waseda.ac.jp>$
$Date: Mon Mar 8 16:36:13 1999$
=end
class Properties
=begin
Class Properties
This class is *not* Thread-Safe.
=end
include Enumerable
attr_accessor(:default)
=begin
Properties object for dafault values.
=end
# @changed
# whether is changed
# @property
# mapping key to value
# @desc
# description lines
# @index
# mapping key -> (line number in @desc)
def initialize(default=nil)
=begin
Make an empty Properties with specified default values.
=end
@default = default
@changed = true
@property = {}
@desc = []
@index = {}
end
def setProperty(key, val)
=begin
Sets a value <var>val</var> to property
which has the specified name <var>key</var>.
Returns the previous value,
or <code>nil</code> when the property has no value.
=end
p([key, val]) if $DEBUG
@changed = true
old_val = @property[key]
@property[key] = val
# remove description line if val is nil.
if val.nil?
@desc[@index[key]] = nil
end
old_val
end
alias []= setProperty
=begin
operator form of setProperty
=end
def getProperty(key, default_val=nil)
=begin
Returns the value of the property specified by <var>key</var>.
When there is not the property,
returns the default value <var>default</var> if it is specified,
returns <code>nil</code> otherwise.
=end
p([key, default_val]) if $DEBUG
if val = @property[key]
val
else
if (not @default.nil?) and
(val = @default.getProperty(key))
val
else
default_val
end
end
end
alias [] getProperty
=begin
oprerator form of getProperty
=end
def method_missing(mid, *args, &iter)
p([mid.id2name, args]) if $DEBUG
case mid.id2name
when /^(.+)=$/
key = $1
val = args[0]
self.setProperty(key, val)
when /^(.+)$/
key = $1
default_val = args[0]
self.getProperty(key, default_val)
else
raise NameError.new
end
end
def addComment(comment)
=begin
Adds a comment to the tail of the descriptions
=end
# @desc << ('; ' + comment)
@desc << comment
self
end
def list(output=STDERR)
=begin
Lists the contents of this properties
to specified stream <var>output</var>.
=end
output.puts("changed = " + @changed.inspect)
@property.each_pair do |key, value|
# output.lprintln(key, ' = ', value)
output.print(key, ' = ', value.inspect, "\n")
end
nil
end
alias dump list
def load(input)
=begin
Loads properties from <var>input</var>.
<var>input</var> must be IO or String(filename).
=end
case input
# input stream
when IO
loadStream(input)
# file name
when String
input = File.expand_path(input)
file = File.open(input)
loadStream(file)
else
raise 'Properties:invalid input'
end
self
end
public(:load)
private
def loadStream(str)
=begin
Loads descriptions from the stream <var>str</var>.
=end
@changed = false
@desc = []
@index = {}
line_num = 0
while line = str.gets
line.strip!
# line = Kconv.tolocal(line)
@desc[line_num] = line
if line == ''
# empty line -> nop
elsif line =~ /^\s*;.*$/
# comment -> nop
elsif line =~ /^\s*#.*$/
# comment -> nop
elsif line =~ /^\s*([^\s=]+)\s*=\s*(.+)\s*$/
key, val = $1, eval($2)
# p [key, val]
@property[key] = val
@index[key] = line_num
else
# error (should some exception be raised?)
STDERR.print("Properties:invalid description:#{$.}\n")
end
line_num += 1
end
end
public
def save(output)
=begin
Saves properties to <var>outptu</var>.
<var>output</var> must be IO or String(filename).
=end
case output
# output stream
when IO
updateDesc
saveStream(output)
# filename
when String
updateDesc
output = File.expand_path(output)
file = File.open(output, 'w')
saveStream(file)
file.close
else
p output.type
raise 'Properties:invalid output'
end
self
end
def each(*args, &iter)
@property.each(*args, &iter)
end
def each_key(*args, &iter)
@property.each_key(*args, &iter)
end
def each_pair(*args, &iter)
@property.each_pair(*args, &iter)
end
private
def updateDesc
=begin
Reflects current properties to descriptions.
=end
if @changed
@property.each_pair do |key, val|
# key is new property
if @index[key].nil?
@index[key] = @desc.length
end
# update the description line.
@desc[@index[key]] = "#{key} = #{val.inspect}"
end
end
self
end
def saveStream(str)
=begin
Saves properties to output stream <var>str</var>.
=end
@desc.each do |line|
# str.lprintln(line) unless line.nil?
str.print(line, "\n") unless line.nil?
end
end
end
syntax highlighted by Code2HTML, v. 0.9.1