App::Config - Perl5 extension for managing global application configuration information.
use App::Config;
my $cfg = App::Config->new();
$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
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.
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).
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';
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.
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".
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).
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;
}
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 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.
the current line number 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 READING A CONFIGURATION FILE for more details.
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.
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;
}
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)
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)
The GLOBAL option allows default values to be set for the ARGCOUNT, EXPAND, CMDARG and VALIDATE options for all variables. 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'.
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
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().
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.
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 (see GLOBAL in DESCRIPTION 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.
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 (see GLOBAL in DESCRIPTION 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.
Variable values specified in a configuration file (see 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 (see GLOBAL in <DESCRIPTION> 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.
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 (see GLOBAL in DESCRIPTION above) then this value will be used as the default VALIDATE for each variable unless otherwise specified.
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.
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
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
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
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.
Andy Wardley, <abw@cre.canon.co.uk>
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. Special thanks to those who sent patches:
GLOBAL arguments
getpw*() check for Win32 compatibility
$Revision: 1.9 $
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.
printf(3C)
The man page for the printf() function, for a description of
the format parameter to the ERROR routine.
http://www.cre.canon.co.uk/perl/
The module which provided inspiration and ideas for the development of App::Config.