I have a module misc
which is used by a few scripts. Each script accept two standard options (-help
and -verbose
) as well as a bunch of its own ones.
So, every scripts now has
my ($verbose,$quiet) = (1,0);
my $help = undef;
...
GetOptions("verbose|v+" => \$verbose, "quiet|q+" => \$quiet, "help|h" => \$help,
....)
or die "GetOptions: error (see above)\n";
if (defined $help) { usage(); exit; }
$verbose -= $quiet;
which is already boring.
Now, I want the misc
functions to be aware of the value of $verbose
too, so I have to move $verbose
et al to misc
and use $misc::verbose
in scripts:
misc:
our $verbose = 1;
my $quiet = 0;
our $help = undef;
our %common_options = ("verbose|v+" => \$verbose, "quiet|q+" => \$quiet, "help|h" => \$help);
sub set_verbose () { $verbose -= $quiet; }
script:
GetOptions(\%misc::common_options,"verbose|v","quiet|q","help|h",
"count=i" => \$count, "start=i" => \$start, "mincoverage=i" => \$mincoverage,
"output=s" => \$output, "input=s" => \$input, "targets=s" => \$targets)
or die "GetOptions: error (see above)\n";
if (defined $misc::help) { usage(); exit; }
misc::set_verbose();
which does not look much better (and appears to not work anyway, at least -help
is ignored).
So, what do people use for command line options shared between modules and scripts?
Personally, I do it simpler:
use a hash to store command line options
GetOptions(\%args, "xxx1","xxx2");
Pass that hash - as is - to ANY classes' constructrs, or module setters
my $object = Class1->new(%args, %constructor_args);
Module2::set_args(\%args); #
Argument setter in the module would be:
# Module2
our %args;
sub set_args { %args = %{ shift }; }
This ensures that:
I NEVER have to worry about moving parameters from scope to scope and having to modify some calls. They are ALL passed around 100% of needed places
Neat and non-messy code. Since we are broadcasting, we don't need to worry about subscribers' individual needs.
Pattern easily replicated to ALL classes you own.
As a matter of fact, if you want to be extra crafty, you can even replace Module2::set_args(\%args);
calls for several classes with a smart code that:
Reads in a list of loaded modules
Checks which of those modules implements set_args()
call via UNIVERSAL::can()
Calls the supporting modules' set_args()
call
The latter makes the code even cleaner, in that N calls to set_args()
one for each non-class module is are all replaced by one set_all_modules_args()
call.