----------------------
It occasionally happens that one has a command or set of commands for which one wishes to provide several options/flags that a player can set to customize the command's behavior for him/herself. Making each option a separate property is a bit expensive, especially when the option in question is merely a boolean flag that gets set to false in most cases. This package provides an alternative, as well as providing a uniform set of commands for setting these flags/options and checking that the values given are of appropriate types.
Instead of needing several properties, only one is required to store a list containing values for all of the options. An "option package" (pkg, below) is then an object of this class, which provides routines for manipulating such lists.
The set of option names is divided into a set of "real" options, those whose names will actually appear in a given list, and "extras" which are either synonyms for or represent combinations of real options.
pkg:add_name(name) adds name to .names (remove it from .extras if there)
pkg:add_name(name,1) adds name to .extras (remove it from .names if there)
=> 1 - ok, 0 - already added, E_INVARG - illegal name, E_PERM
pkg:remove_name(name) remove name from either .names or .extras
=> 1 - ok, 0 - not present, E_PERM
For setting or retrieving values we have
pkg:get(options,name)
=> value (or 0 if name isn't a real option)
pkg:set(options,name,value)
=> revised options (or string error message if something goes wrong)
By default, a given option can only be a boolean flag, having one of the values 0 (absent from the list), or 1 (present in the list). :set translates 0/""/{} to 0 and any other non-object value to 1.
One may however designate a wider range of possible values for an option "foo" by either installing one of
pkg.type_foo
-- list of allowed types,
e.g., {NUM,STR} => must be a number or a string
e.g., {OBJ,{OBJ}} => must be an object or a list of objects
for anything fancier use:
pkg:check_foo(value)
=> string error message or {value munged as desired}
In general, the only restriction on option values is that 0 is the only false value; setting an option to "" or {} sets it to 0. Every option defaults to 0, and no matter what you install as .type_foo or :check_foo(), 0 will always be a legal value for option "foo".
When presented with an option that is in .extras, :set will typecheck the value as described, however, then :actual(name, value) will be called to obtain a list of {name-of-real-option, value} pairs indicating which combination of real options should be set.
Other verbs
pkg:parse(args,...)
parses the command line arguments of a @whatever_option command
=> {optionname, value} if the player wants to set an option
=> {optionname} if the player wants to view an option
=> string error message otherwise
one may install pkg:parse_foo to parse arguments for option "foo"
!foo => {"foo",0} (:parse_foo not called)
foo= => {"foo",0} (:parse_foo not called)
-foo => {"foo",0} (:parse_foo not called)
+foo => pkg:parse_foo("foo",1)
foo=word => pkg:parse_foo("foo","word")
foo word1 word2 => pkg:parse_foo("foo",{"word1","word2"})
foo is word1 word2 => pkg:parse_foo("foo",{"word1","word2"})
pkg:show(options,name|list of names)
=> list of strings describing the current value of the named option(s).
calls pkg:show_foo(options,list of names) or
refers to pkg.show_foo
to describe option "foo"
(see sources for details... at some point I'll finish writing this... --Rog)