Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Processing arguments with Getopt::Long

by MKJ747 (Acolyte)
on Feb 18, 2011 at 15:34 UTC ( [id://888928]=perlquestion: print w/replies, xml ) Need Help??

MKJ747 has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I am using Getopt::Long to process command line arguments. For a string option, I would like to call a function and then process that value. I'm not sure how the value itself is captured for use in the function. Here's a simple example:

use strict; use Getopt::Long; my $result = GetOptions ( "c=s" => \&COMPTO, '<>' => sub {print "\nThat is not a valid parameter\n";}, ); sub COMPTO {print "\nGenerate Output for <some string> \n";}

In the example above, I run "program.pl -c <some string>", and I would to capture the string "<some string>" so I can use that value in the function COMPTO that is called. The Getopts::Long documentation implies you can do this, but I'm not sure of the syntax. Thank you.

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

    The option and its value are passed as arguments to the function, i.e. you can access them (as usual) via @_, or $_[0] (option name) and $_[1] (value).

    ... sub COMPTO { my ($optname, $value) = @_; print "\nGenerate Output for option -$optname : value=$value\n"; } __END__ $ ./888928.pl -c foo Generate Output for option -c : value=foo

    (update: changed to named variables, for readability)

      ++

      I think your code snippet would make an excellent addition to the Getopt::Long POD. Please consider sending a patch via perlbug.

        You're the one who wants it in; you do the work!

      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.

        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

        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.

        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:

Re: Processing arguments with Getopt::Long
by toolic (Bishop) on Feb 18, 2011 at 16:14 UTC
    You have received your answer, but I would like to point out that another place to look for code examples is on CPAN.

    If you follow the MANIFEST link from Getopt::Long, you will see all the files associated with the module.

    This shows an example of what you are trying to do: examples/parsetime.pl

      Thank you, Toolic. Yes, I'm still seeking an answer to the conditional question no t without c. I will check out these links - thanks very much.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://888928]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-25 19:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found