def enum key, *values
aliases = {}
if values.last.is_a? Hash
values.pop.each do |value, synonyms|
if synonyms.is_a? Array
synonyms.each do |synonym| aliases.store synonym, value end
else
aliases.store synonyms, value
end
end
end
values.each do |value|
aliases.store value, value
end
define_method key do
name = ivar_name key
value = instance_variable_get(name) if instance_variables.include? name
value || values.first
end
define_method "#{key}=" do |arg|
if arg
arg = aliases.fetch arg do
aliases.fetch arg.to_s.downcase.gsub(/[ \-]/, '_').to_sym, arg
end
if values.any? do |val| val === arg end
instance_variable_set(ivar_name(key), arg)
else
valid = values.collect do |val| val.inspect end.join ', '
raise ArgumentError,
"Invalid value '#{arg.inspect}' for #{key}. Valid values are: #{valid}"
end
else
instance_variable_set ivar_name(key), values.first
end
end
end