NAME App::Config - Perl5 extension for managing global application configuration information. SYNOPSIS use App::Config; my $cfg = new App::Config; $cfg->define("foo"); # very simple variable definition $cfg->set("foo", 123); # trivial set/get examples $fval = $cfg->get("foo"); $cfg->foo(456); # direct variable access $cfg->cfg_file(".myconfigrc"); # read config file $cfg->cmd_line(\@ARGV); # process command line OVERVIEW App::Config is a Perl5 module to handle global configuration variables for perl programs. The advantages of using such a module over the standard "global variables" approach include: * Reduction of clutter in the main namespace. * Default values can be specified. * Multiple names (aliases) can refer to the same variable. * Configuration values can be set directly from config files and/or command line arguments. * Data values can be automatically validated by pattern matching (e.g. "\d+" to accept digits only) or through user-supplied routines. * User-defined routines can be called automatically when configuration values are changed. PREREQUISITES App::Config requires Perl version 5.004 or later. If you have an older version of Perl, please upgrade to latest version. Perl 5.004 is known to be stable and includes new features and bug fixes over previous versions. Perl itself is available from your nearest CPAN site (see http://www.perl.com/CPAN). INSTALLATION To install this module type the following: perl Makefile.PL make make install The 'make install' will install the module on your system. You may need root access to perform this task. If you install the module in a local directory (for example, by executing "perl Makefile.PL LIB=~/lib" in the above - see `perldoc MakeMaker' for full details), you will need to ensure that the PERL5LIB environment variable is set to include the location, or add a line to your scripts explicitly naming the library location: use lib '/local/path/to/lib'; DESCRIPTION USING THE App::Config MODULE To import and use the App::COnfig module the following line should appear in your Perl script: use App::Config; App::Config is implemented using object-oriented methods. A new App::Config object is created and initialised using the App::Config->new() method. This returns a reference to a new App::Config object. my $cfg = App::Config->new(); This will create a reference to a new App::Config with all configuration options set to their default values. You can initialise the object by passing a hash array reference containing configuration options: $cfg = App::Config->new( { CASE => 1, FILEPARSE => \&my_parser, ERROR => \&my_error, } ); The following configuration options may be specified. Some of these use default values as may be specified in the GLOBAL configuration option. CASE Determines if the variable names are treated case sensitively. Any non-zero value makes case significant when naming variables. By default, CASE is set to 0 and thus "Variable", "VARIABLE" and "VaRiAbLe" are all treated as "variable". ERROR Specifies a user-defined error handling routine. A format string is passed as the first parameter, followed by any additional values, as per printf(3C). FILEPARSE Specifies a user-defined routine for parsing a configuration file. The function is called by `cfg_file()' and is passed a reference to the App::Config object and the name of the file to parse. The routine should update any variable values directly. The return value is expected to be 1 to indicate success or 0 to indicate failure. This value is returned directly from `cfg_file()'; Pseudo-Code Example: $cfg = App::Config->new( { FILEPARSE => \&my_parser } ); sub my_parser { my $cfg = shift; my $file = shift; # open file, read lines, etc. # ... $cfg->set($variable, $value); # set variable value # close file, etc. return 1; } LINEPARSE Instead of providing a routine to parse the entire config file, LINEPARSE can be used to define a function to handle each line of the config file. The `cfg_file()' routine reads the file and passes each line to the LINEPARSE function, where defined. Four parameters are passed to the LINEPARSE function; a reference to the App::Config object, the config filename, the current line within the file and the line of text itself (the filename and line number are useful for reporting errors). Note that `cfg_file()' does some elementary pre- processing before calling the LINEPARSE function. See the section on "READING A CONFIGURATION FILE" for more details. The function should return 1 to indicate that the line has been successfully parsed, or 0 to indicate that no action was taken and the default line parser should now be used for this line. CMDPARSE Specifies a user-defined routine for parsing the command line. The function is called by cmd_line() and is passed a reference to the App::Config object and a reference to a list of command line arguments (usually @ARGV). The function is required to set variable values directly and return 1 or 0 to indicate success or failure, as is described in the FILEPARSE section above. ARGPARSE Just as a LINEPARSE routine can be defined to parse each line of a config file, an ARGPARSE routine can also be specified to parse each command line argument. The function is called from cmd_line() and is passed a reference to the App::Config object through which variable values can be manipulated. Other parameters passed are the command line argument in question (e.g. `"-v"'), the name of the variable to which it corresponds (e.g. `"verbose"') and a reference to the remaining argument list. The function is expected to modify the argument list if necessary, shifting off additional parameters where required. A pseudo-code example is shown: my $cfg = App::Config->new( { ARGPARSE => \&my_arg_parse, } ); sub my_arg_parse { my $cfg = shift; my $arg = shift; my $var = shift; my $argvref = shift; VAR: { $var eq 'verbose' && do { $cfg->set($var, 1); last VAR; }; # this time, look at $arg instead of $var $arg eq '-f' && do { $cfg->set($var, shift(@$argvref)); # should error check last VAR; }; # not interested in anything else # (let default parser have a go) return 0; } # we processed it so return 1 return 1; } =item CMDENV The CMDENV option is used to specify the name of an environment variable which may contain default command line options. If defined, the variable is examined by the cmd_line() routine where it is split into whitespace separated tokens and parsed along with the rest of the command line options. Environment variable options are processed before any real command line options. Note that the variable is split on whitespace and does not take into account quoted whitespace. Thus 'foo "bar baz" qux' will be split into the tokens 'foo', '"bar', 'baz"' and 'qux'. This will be fixed in a future release. From the Unix shell: $ SPLATOPTS="-z -f foobar" Perl App::Config usage: my $cfg = App::Config->new( { CMDENV => "SPLATOPTS" } ); $cfg->cmd_line(\@ARGV); # parses ("-z", "-f", "foobar", @ARGV) ENDOFARGS The ENDOFARGS option can be used to specify the marker that signifies the end of the command line argument list. Typically, and by default, this is '--'. Any arguments appearing in the command line after this token will be ignored. my $cfg = App::Config->new( { ENDOFARGS => "STOP" } ); @args = qw(-f -g -h STOP -i -am -ignored); $cfg->cmd_line(\@args); # @args now contains qw(-i -am -ignored) GLOBAL The GLOBAL option allows default values to be set for the ARGCOUNT, EXPAND, CMDARG and VALIDATE options for all variables. the section on "DEFINING VARIABLES" below describes these options in detail. The CMDARG global option, when set to any true value, specifies that the command line option for any variable should be of the form "-variable". Any aliases specified for a variable can also be used in this way. e.g. my $cfg = App::Config->new({ GLOBAL => { ARGCOUNT => 1, CMDARG => 1 } }); $cfg->define("foo", { ALIAS => 'bar' }); The GLOBAL ARGCOUNT parameter specifies that the foo variable expects an argument. An ARGCOUNT option specified in the `define()' method call would override this default. The GLOBAL CMDARG option specifies that the 'foo' variable should be specified on the command line as '-foo'. The ALIAS name for foo can also be specified as such: '-bar'. DEFINING VARIABLES The `define()' function is used to pre-declare a variable and specify its configuration. $cfg->define("foo"); In the simple example above, a new variable called "foo" is defined. A reference to a hash array may also be passed to specify configuration information for the variable: $cfg->define("foo", { DEFAULT => 99, ALIAS => 'metavar1', }); The following configuration options may be specified DEFAULT The DEFAULT value is used to initialise the variable. The variable remains set to this value unless otherwise changed via `set()', `cfg_file()' or `cmd_line()'. ALIAS The ALIAS option allows a number of alternative names to be specified for this variable. A single alias should be specified as a string, multiple aliases as a reference to an array. e.g.: $cfg->define("foo", { ALIAS => 'metavar1', }); or $cfg->define("bar", { ALIAS => [ 'metavar2', 'metalrod', 'boozer' ], }); In the first example, `$cfg->set("metavar1")' (or any other variable-related function) is equivalent to `$cfg- >set("foo")'. Likewise for the second example, with all 3 aliases defined. CMDARG When processing a list of command line arguments, flags may be used to refer to certain variable values. For example, `- v' is a common flag indicating verbose mode. The 'verbose' variable might be defined as such: $cfg->define("verbose", { CMDARG => '-v', }); If the `cmd_line()' function detects `-v' in the command line arguments, it will update the 'verbose' value. See also the ARGCOUNT option below which influences the variable values that are set by the command line processing function. A variable may have more than one related command line argument. These can be specified by passing a reference to an array of arguments: $cfg->define("verbose", { CMDARG => [ '-v', '-V' ], }); If the GLOBAL CMDARG variable is set (the GLOBAL manpage above) then the default CMDARG for each variable will be its name (and any aliases) prefixed by a dash, e.g. '-verbose'. Any CMADRG value specifically set will override this default. ARGCOUNT Some variables are intended to be simple flags that have a false/true (zero/non-zero) value (e.g. the 'verbose' example above) while others may require mandatory arguments (e.g. specifying a file: `"-f filename"'). The ARGCOUNT value is used to determine if an additional argument is expected (`ARGCOUNT => 1') or not (`ARGCOUNT => 0'). When ARGCOUNT is 1, `cfg_file()' passes the rest of the config line (after the opening variable name has been removed) as the argument value and `cmd_line()' passes the next argument from the command line argument list (usually @ARGV). When ARGCOUNT is 0, both functions pass the value 1 to set the variable to a true state. The default ARGCOUNT value is 0. If the GLOBAL ARGCOUNT variable is set (the GLOBAL manpage above) then this value will be used as the default ARGCOUNT for each variable unless otherwise specified. NOTE: Although any non-zero value can be used to indicate the presence of an additional argument, this option may be extended in the future to handle multiple arguments. The behaviour associated with any value other than 1 or 0 may change in subsequent versions. EXPAND Variable values specified in a configuration file (see the section on "READING A CONFIGURATION FILE") may contain environment variables, other App::Config variables and/or users' home directories specified in tilde notation (e.g. ~abw). The EXPAND option specifies if these variables should be replaced with their relevant values. By default EXPAND is set to 1 (expansion) but can be set to 0 to disable the feature. If the GLOBAL EXPAND variable is set (the GLOBAL manpage above) then this value will be used as the default EXPAND for each variable unless otherwise specified. Items are expanded according to the following rules: * A directory element specified in tilde notation is expanded to the full directory path it represents (e.g. ~abw/lib => /user/abw/lib). A tilde by itself expands to the home directory of the current user (e.g. ~/lib => /users/abw/lib). If a non-existant user is specified or it is not possible to determine the home directory of the user, the tilde notation is left unexpanded (e.g. ~nosuchuser/lib). * A variable enclosed in braces and prefixed with a dollar symbol (e.g. ${HOME}) is assumed to be an environment variable and is expanded as such. A non-existant variable will be replaced by an empty string, as is typical in UNIX shell expansion (e.g. ${DUD}/lib => /lib). * A variable enclosed in parenthesis and prefixed with a dollar symbol (e.g. $(ROOT)) is assumed to refer to another variable defined in the current App::Config object. Case sensitivity is applied as per the current CASE setting and non-existant variables are replaced by an empty string as per environment variables (e.g. $(mipspelt)/lib => /lib). * A variable prefixed with a dollar and with no enclosing braces or parenthesis (e.g. $root/lib) is first interpreted as an App::Config variable and if not resolved, as an environment variable. If the variable cannot be evaluated in either context it is ignored and the original text is left unmodified. VALIDATE Each variable may have a sub-routine or regular expression defined which is used to validate the intended value that is set by `cfg_file()' and `cmd_line()'. If VALIDATE is defined as a simple string, it is applied as a regular expression to the value read from the config file or command line. If the regex matches, the value is set. If not, a warning message is generated. VALIDATE may also be defined as a reference to a sub-routine which takes as its arguments the name of the variable and its intended value. The sub-routine should return 1 or 0 to indicate that the value is valid or invalid, respectively. An invalid value will cause a warning error message to be generated. If the GLOBAL VALIDATE variable is set (the GLOBAL manpage above) then this value will be used as the default VALIDATE for each variable unless otherwise specified. ACTION The ACTION option allows a sub-routine to be bound to a variable that is executed whenever the variable is set. The ACTION is passed a reference to the App::Config object, the name of the variable and the value of the variable. The ACTION routine may be used, for example, to post-process variable data, update the value of some other dependant variable, generate a warning message, etc. Example: sub my_notify { my $cfg = shift; my $var = shift; my $val = shift; print "$variable set to $value\n"; } Be aware that calling `$cfg->set()' to update the variable from within the ACTION function will cause a recursive loop as the ACTION function is repeatedly called. This is probably a bug, certainly a limitation. READING AND MODIFYING VARIABLE VALUES App::Config defines two methods to manipulate variable values: set($variable, $value); get($variable); Both functions take the variable name as the first parameter and `set()' takes an additional parameter which is the new value for the variable. `set()' returns 1 or 0 to indicate successful or unsuccessful update of the variable value. If there is an ACTION routine associated with the named variable, the value returned will be passed back from `set()'. The `get()' function returns the current value of the variable. Once defined, variables may be accessed directly as object methods where the method name is the same as the variable name. i.e. $cfg->set("verbose", 1); is equivalent to $cfg->verbose(1); Without parameters, the current value of the variable is returned. If a parameter is specified, the variable is set to that value and the original value (before modification) is returned. $cfg->age(28); $cfg->age(29); # sets 'age' to 29, returns 28 READING A CONFIGURATION FILE App::Config can be used to read configuration files and automatically update variable values based on the contents of the file. $cfg->cfg_file("$HOME/.myapprc"); The `cfg_file()' function reads each line of the specified configuration file and processes them according to the following rules: * Any lines ending with a backslash '\' are treated as continuation lines. The following line is appended to the current line (and any subsequent continuation lines) before any further processing. * Any blank lines or lines starting with a '#' (i.e. comments) are ignored. * Leading and trailing whitespace is ignored. * The line is separated at the first whitespace character or at the first `'='' character (surrounding whitespace is ignored). * A variable by itself with no corresponding value will be treated as a simple flag if it's ARGCOUNT is 0. In this case, the value for the variable will be set to 1. The following example demonstrates a typical configuration file: # simple flag (same as " verbose 1" or "verbose = 1") verbose # the following lines are all equivalent file /tmp/foobar file = /tmp/foobar file=/tmp/foo PARSING THE COMMAND LINE By specify CMDARG values for defined variables, the `cmd_line()' function can be used to read the command line parameters and automatically set variables. When an command line argument matches a CMDARG value, the variable it relates to is updated. If the variable has an ARGCOUNT of 0, it will be assigned the value 1 (i.e. the flag is set). A variable with an ARGCOUNT of 1 will be set with the next value in the arguments. Users familiar with getopt(3C) will recognise this as equivalent to adding a colon after an option letter (e.g. `"f:"'). An error is generated if the argument starts with a '-'. The special option "--" may be used to delimit the end of the options. `cmd_line()' stops processing if it finds this option. Example variable definition: $cfg->define("verbose", { CMDARG => '-v', ARGCOUNT => 0, # default anyway }); $cfg->define("file", { CMDARG => '-f', ARGCOUNT => 1, # expects an argument }); Command-line options: -v -f foobar Variable values after calling `cmd_line(\@ARGV)': verbose: 1 file: foobar KNOWN BUGS AND LIMITATIONS The following list represents known limitations or bugs in App::Config or ways in which it may be improved in the future. Please contact the author if you have any suggestions or comments. * An ACTION sub-routine may not update its variable via the $cfg- >set() method. This causes the ACTION function to be re- executed, starting a recursive loop. * More extensive variable validation (not using user-defined functions), perhaps by defining standard classes (e.g. numeric, filename, list, etc). Variable validation may be also extended to allow manipulation of the data as well (e.g. splitting a string into a list). * Further extend command line parsing. Maybe allow regexes to be specified for matches (e.g. `"-v(erbose)"') and handle different command line characters other than `'-'' (e.g. `+flag @file'). This may also tie in with long (--) and short (-) options and defining recognised 'classes' of options. * ARGCOUNT should be able to indicate nargs > 1 and have cmd_line extract them accordingly. Perhaps have types, e.g. boolean, single, multiple. The validate function could additionally take an array ref which contains code refs or regex's to match each arg. Should also be able to handle multiple options that can be specified separately, e.g. `- I/usr/include' `-I/user/abw/include'. * An ACCESS parameter could specify which actions may update a variable: set(), cfg_file() and/or cmd_line(). * Allow variables to have related environment variables which are parsed by an env_vars() function. AUTHOR Andy Wardley, `' Web Technology Group, Canon Research Centre Europe Ltd. App::Config is based in part on the ConfigReader module, v0.5, by Andrew Wilcox (currently untraceable). Thanks to all the people who have reported bugs and made suggestions. Extra special thanks to those who sent patches: Mik Firestone * GLOBAL arguments Blair Zajac * getpw*() check for Win32 compatibility REVISION $Revision: 1.7 $ COPYRIGHT Copyright (C) 1997,98 Canon Research Centre Europe Ltd. All Rights Reserved. This module is free software; you can redistribute it and/or modify it under the term of the Perl Artistic License. SEE ALSO Andy Wardley's Home Page http://www.kfs.org/~abw/ Canon Research Centre Europe http://www.cre.canon.co.uk/perl/ The ConfigReader module. The module which provided inspiration and ideas for the development of App::Config.