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

Thank you Eliya. That makes perfect sense. I was overlooking the obvious (PERL newbie)

I have another quick question: Do you know the best way to make an option dependent on another? For example, in the code given above, I also add an option t that also requires a value, but the program will exit with an error if option t exists but not option c

use strict; use Getopt::Long; my $result = GetOptions ( "c=s" => \&COMP1, "t=s" => \&COMP2, # COMP2 will not be called if option c is +null? '<>' => sub {print "\nThat is not a valid parameter\n";}, ); sub COMP1 {print "\nOption -$_[0] is value=$_[1]\n";} sub COMP2 {print "\nOption -$_[0] is value=$_[1]\n";}

One thought is to load a variable and process them later, like this:

use strict; use Getopt::Long; my $COMP1 = 0; my $COMP2 = 0; my $result = GetOptions ( "c=s" => \$COMP1, "t=s" => \$COMP2, '<>' => sub {print "\nThat is not a valid parameter\n";}, ); if (!$COMP1) { if ($COMP2) { print "\nOption t won't run without option C"; } }

But I imagine there is a better way using GetOptions(). Ideas? Thank you.

Replies are listed 'Best First'.
Re^3: Processing arguments with Getopt::Long
by Eliya (Vicar) on Feb 18, 2011 at 17:17 UTC

    I'm not aware of any way to directly declare option dependencies with Getopt::Long.

    In theory, you could do ugly things like replacing the option handlers while processing the options, but whether that's "better" than your attempt is questionable... :)

    my $result = GetOptions ( "c=s" => \&COMPT1, "t=s" => \&COMPT2, '<>' => sub {print "\nThat is not a valid parameter\n";}, ); sub COMPT1 { my ($optname, $value) = @_; print "Option -$optname is value=$value\n"; # replace error handler for -t with real handler $optname->{linkage}{t} = sub { my ($optname, $value) = @_; print "Option -$optname is value=$value\n"; }; }; sub COMPT2 { # error handler print "Option -t requires option -c\n"; }; __END__ $ ./888928.pl -c foo -t bar Option -c is value=foo Option -t is value=bar $ ./888928.pl -t bar Option -t requires option -c

    Note that $optname is an object1, via which you can access the bindings, for example. (I just Data::Dumper'ed the object to see what's in it — maybe you can find a way to do it properly with (documented) methods when you peruse the docs carefully enough...)

    Also, the dependency is only "one-way", i.e. it's assumed that -c comes before -t on the command line, and that -c alone makes sense...  If you want "-c without -t" to also be an error, you'll necessarily have to wait until the entire command line has been processed, before checking for failed dependencies.

    ___

    1

    • with newer versions of the module only
    • the object strigifies to the option name

      Thanks for taking the time to go through this, Eliya - great example. I will weigh this with the If conditional option and see what looks better. I'm still learning, and every time I figure something out I'm assuming there's a slicker way to do it. Thanks for helping out!

      I don't agree with messing with internals of an object (and one that's undocumented at that) just to avoid an extremely simple "if".
        I don't agree with messing with internals of an object...

        Me neither.  Which is why I said "...but whether that's "better" than your (the OP's) attempt is questionable... :)".  I thought that was clear enough.

        Still, learning comes from exploration, so it's not entirely useless to just play with different approaches... even if you're not going to use them in production code in the end.

Re^3: Processing arguments with Getopt::Long
by ikegami (Patriarch) on Feb 18, 2011 at 16:31 UTC

    the program will exit with an error if option t exists but not option c

    It shouldn't, and it doesn't for me.

    >perl a.pl -t a Option -t is value=a >perl a.pl -c a Option -c is value=a >perl a.pl -t a -c a Option -t is value=a Option -c is value=a >perl a.pl -c a -t a Option -c is value=a Option -t is value=a

    If you're saying your program should exit, then yes, you have to add an check afterwards.

      No, in my first example, the code is not setup to exit if c is not defined, because I wasn't sure how to do it. Sorry if I wasn't clear on that - just added the example as a change to the original example I posted. I see later post with examples to check, so I will check that out. Thanks for answering.

Re^3: Processing arguments with Getopt::Long
by ig (Vicar) on Feb 21, 2011 at 19:25 UTC
    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:

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