Option and Configuration Processing Made Easy
by Jon Allen
|
Pages: 1, 2, 3
Advanced Usage
In many cases the default behaviour invoked by loading the module will be all you need, but Getopt::ArgvFile can also cater to more specific requirements.
User-Specified Config Files
Suppose your users want to save different sets of options and specify which one to use when they run your program. This is possible using the @ directive on the command line:
varos:~/writing/argvfile jj$ cat jj.conf
--name JJ
varos:~/writing/argvfile jj$ ./hello
Hello, Jon Allen
varos:~/writing/argvfile jj$ ./hello @jj.conf
Hello, JJ
Note that there's no extra programming required to use this feature; handling @ options is native to Getopt::ArgvFile.
Changing the Default Config Filename or Location
Depending on your target audience, the naming convention offered by Getopt::ArgvFile for config files might not be appropriate. Using a dotfile (.myscript) will render your user's config file invisible in his file manager or when listing files at the command prompt, so you may wish to use a name like myscript.conf instead.
Again, it may also be helpful to allow for default configuration files to appear somewhere other than the user's home directory, for example, if you need to allow system-wide configuration.
A further consideration here is PAR , the tool for creating standalone executables from Perl programs. PAR lets you include data files as well as Perl code, so you can bundle a default settings file using a command such as:
pp hello -o hello.exe -a hello.conf
which will be available to your script as $ENV{PAR_TEMP}/inc/hello.conf.
I mentioned earlier that Getopt::ArgvFile can load arbitrary config files if the filename appears with the @ directive on the command line. Essentially, what the module does when loaded with:
use Getopt::ArgvFile home=>1;
is to prepend @ARGV with @$ENV{HOME}/.scriptname, then resolve all @ directives, leaving @ARGV with the contents of the files. This means that running the script as:
myscript --name=JJ
is basically equivalent to writing:
myscript @$ENV{HOME}/.myscript --name-JJ
To load other config files, Getopt::ArgvFile supports disabling the automatic @ARGV processing and triggering it later. With a little manipulation of @ARGV first, you can make:
myscript --name=JJ
equivalent to:
myscript @/path/to/default.conf @/path/to/system.conf @/path/to/user.conf \
--name=JJ
which will load the set of config files in the correct priority order.
All you need to do to enable this feature is change the use statement to read:
use Getopt::ArgvFile qw/argvFile/;
Loading the module in this way tells Getopt::ArgvFile to export the function argvFile(), which your program needs to call to process the @ directives, and also prevents any automated processing from occurring.
Here's an example that first loads a config file from the application bundle (if packaged by PAR) and then from the directory containing the application binary:
use File::Basename qw/basename/;
use FindBin qw/$Bin/;
use Getopt::ArgvFile qw/argvFile/;
# Define config filename as <application_name>.conf
(my $configfile = basename($0)) =~ s/^(.*?)(?:\..*)?$/$1.conf/;
# Include config file from the same directory as the application binary
if (-e "$Bin/$configfile") {
unshift @ARGV,'@'."$Bin/$configfile";
}
# If we have been packaged with PAR, include the config file from the
# application bundle
if ($ENV{PAR_TEMP} and -e "$ENV{PAR_TEMP}/inc/$configfile") {
unshift @ARGV,'@'."$ENV{PAR_TEMP}/inc/$configfile";
}
argvFile(); # Process @ARGV to load specified config files
You can also use this technique together with File::HomeDir to access the user's application data directory in a cross-platform manner, so that the location of the config file conforms to the conventions set by the user's operating system.
Summary
Getopt::Long provides an easy to use, extensible system for processing command-line options. With the addition of Getopt::ArgvFile, you can seamlessly handle configuration files with almost no extra coding. Together, these modules should be first on your list when writing scripts that need any amount of configuration.
Showing messages 1 through 2 of 2.
- Options with multiple arguments example doesn't seem to work
2008-03-28 03:26:16 Zefrer [Reply]
When trying to use
GetOptions('name=s@{1,}' => \$name);
I get an Error in option spec: "name=s@{1,}" ...
Perl version 5.8.8
Anyone have any ideas as to why?



