in reply to Re^2: Processing arguments with Getopt::Long
in thread Processing arguments with Getopt::Long

the best way to make an option dependent on another?

What is best depends on the circumstances, but here is another way that might be better if you need sequential processing of your arguments:

use strict; use warnings; use Getopt::Long; my %args; my $result = GetOptions ( "c=s" => \&COMP1, "t=s" => sub { if($args{c}) { COMP2(@_); # COMP2 will not be called if option c is n +ull? } else { die 'Warning: arg -t without preceding -c: arg -t igno +red'; } }, '<>' => sub {print "\nThat is not a valid parameter\n";}, ); die "Error: argument processing did not complete successfully" unless( +$result); exit(0); sub COMP1 { print "Option -$_[0] is value=$_[1]\n"; $args{$_[0]} = $_[1]; } sub COMP2 { print "Option -$_[0] is value=$_[1]\n"; $args{$_[0]} = $_[1]; }

Note carefully what happens with out of order (for some definitions of order) arguments:

$ ./test.pl -t asdf -c qwer Warning: arg -t without preceding -c: arg -t ignored at ./test.pl line + 13. Option -c is value=qwer Error: argument processing did not complete successfully at ./test.pl +line 18.

This may not be the result you want.

You can have Getopt::Long stop processing when an error is encountered in the handler by calling die with '!FINISH'.

use strict; use warnings; use Getopt::Long; my %args; my $result = GetOptions ( "c=s" => \&COMP1, "t=s" => sub { if($args{c}) { COMP2(@_); # COMP2 will not be called if option c is n +ull? } else { warn 'Error: arg -t without preceding -c: processing t +erminated'; die '!FINISH'; } }, '<>' => sub {print "\nThat is not a valid parameter\n";}, ); die "Error: argument processing did not complete successfully" unless( +$result); exit(0); sub COMP1 { print "Option -$_[0] is value=$_[1]\n"; $args{$_[0]} = $_[1]; } sub COMP2 { print "Option -$_[0] is value=$_[1]\n"; $args{$_[0]} = $_[1]; }

Given the same "out of order" arguments, this version does not proceed to process the -c argument:

$ ./test.pl -t asdf -c qwer Error: arg -t without preceding -c: processing terminated at ./test.pl + line 13.

But notice that Getopt::Long doesn't return an error indication in this case. It returns with the argument list partially processed. Of course, you could test for this and proceed or not as might be appropriate.

You should also consider whether any processing should be done if there is an error in the arguments. It might be best to analyze all the arguments and terminate if there is an error or process them if all is well. Consider the following case:

use strict; use warnings; use Getopt::Long; my %args; my $result = GetOptions ( "c=s" => \&COMP1, "t=s" => sub { if($args{c}) { COMP2(@_); # COMP2 will not be called if option c is n +ull? } else { warn 'Error: arg -t without preceding -c: processing t +erminated'; die '!FINISH'; } }, '<>' => sub {print "Frobnicating $_[0]\n";}, ); die "Error: argument processing did not complete successfully" unless( +$result); exit(0); sub COMP1 { print "Option -$_[0] is value=$_[1]\n"; $args{$_[0]} = $_[1]; } sub COMP2 { print "Option -$_[0] is value=$_[1]\n"; $args{$_[0]} = $_[1]; }

Which might be called with the following arguments:

$ ./test.pl foo -t bar -c baz Frobnicating foo Error: arg -t without preceding -c: processing terminated at ./test.pl + line 13.

In this case, you might not want your foo frobnicated, or it might be exactly what you want.

In summary, this is a very long winded (and, one hopes, in passing, at least somewhat informative) way of saying that what is best depends on the circumstances but with some imagination almost anything can be done.

Replies are listed 'Best First'.
Re^4: Processing arguments with Getopt::Long
by MKJ747 (Acolyte) on Feb 22, 2011 at 14:46 UTC

    Thanks for the informative answer, ig. This is great stuff and I learned a lot. I appreciate your time.