http://www.perlmonks.org?node_id=241582


in reply to GetOpt::Long usage style

I've always felt that gathering up options for use in any program was rather inelegant anyways. While it's nice to wrap up declaration, default value, and paramater value into one convenient statement it seems to pass over the structure of the problem.

## this is a poorly written demonstrative example use GetOpt::Long; my $args = { verbose => 0, # default false all => '', # default undef skip => [], # default empty }; GetOptions( 'verbose|v' => sub { \$args->{verbose} += 1 }, 'debug|d=i' => \$args->{verbose}, 'all' => \$args->{all}, 'skip|s=s' => sub { push(@{$args->{skip}}, $_[1]) } ); # get a default from the environment. $args->{all} = $ENV{FOO_DEFAULT_ALL} unless (defined($args->{all})); # get a default from a parsed configuration file. $args->{all} = $rcfile->{foo_default}->{all} unless (defined($args->{a +ll})); # get defaults from some arbitrary source. get_foo_defaults($args);

I like to have all my arguments grouped in one place. In other words, I really hate using global variables, especially for something like this. Typically, I'll use a hash reference for convenience. This allows me to group the arguments, pass them around (and change) them easily, and define my 'default' values all in once place. Plus I have once place to look to see what paramaters I expect to keep track of, and one variable to Dump if necessary.

Most of the time I'm gathering paramaters from other sources as well. Such as a configuration file, or environment variables, or sometimes even network sources. So there tends to be more than one place where these values are getting 'filled-in' anyways, and I'm not always starting with the command line options. So it seems wasteful to try and make everything line up under a GetOptions call, especially if you intend to change anything down the line.

Occasionally I enjoy using the subroutine reference 'mode' of GetOpt to do simple things like incrementing a value depeding on how many times it appears on the command line, or doing simple paramater validation before it gets stored to a variable, or even accepting multiple values for a single paramater. These are really handy sometimes, and lining up all my declarations under the GetOptions call simply dosen't work -- I'll need to predeclare a variable anyways.

I also tend to have a few options which modify the same variable anyways, which also keeps you from getting away with a 1:1 mapping. I like to let the user set debugging output specifically: '-d 3', as well as incrementally: '-v -v -v'. So predeclaring my paramater values here is also convenient.

Also, in my own preference, I don't care wether or not the named paramater 'verbose' actually modifies a variable named 'verbose', it could well be named 'debug' or 'output_level' or any other name that makes sence for the context it's being used in. What matters is, the rest of my program looks for a variable named 'verbose'; the name of the paramater is really kind of irrelevant -- and is only used once in once place, whereas the value is used in multiple places.

It all comes down to personal preference, and necessity, I guess. And my preferences and needs have resulted in my using a structure similar to the above almost exclusively. That's just me, though.