Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Getopt::Long subroutine question

by brassbin (Novice)
on Jul 22, 2013 at 21:15 UTC ( #1045727=perlquestion: print w/ replies, xml ) Need Help??
brassbin has asked for the wisdom of the Perl Monks concerning the following question:

hi,

i'm trying to invoke a subroutine on the occurrence of certain option, say something like this

GetOptions( 'test=s{3}' => \&sub1 ); sub sub1 { print @_ }

running the script with

prog --test a b c

would yield a result like this

test a

test b

test c

as if the sub was called 3 times, each with 1 of the 3 values passed in, how do i make it so that all 3 values of the option are passed to @_ once with one invocation of the subroutine?

Comment on Getopt::Long subroutine question
Download Code
Re: Getopt::Long subroutine question
by Loops (Hermit) on Jul 22, 2013 at 21:27 UTC

    You can't use a sub reference like that if your desire is for it to receive all the parameters at once. Here is an alternative:

    use strict; use warnings; use Getopt::Long; my @test; GetOptions( 'test=s{3}' => \@test ); sub sub1 { print "@_" }; sub1 @test if @test;
Re: Getopt::Long subroutine question
by 2teez (Priest) on Jul 23, 2013 at 03:48 UTC

    hi brassbin,
    *as if the sub was called 3 times, how do i make it so that all 3 values of the option are passed to @_ once with one invocation of the subroutine?

    Checking the User-defined subroutines to handle options in Getopt::Long documentation, it says

    Ultimate control over what should be done when (actually: each time) an option is encountered on the command line can be achieved by designating a reference to a subroutine (or an anonymous subroutine) as the option destination. When GetOptions() encounters the option, it will call the subroutine with two or three arguments. The first argument is the name of the option. (Actually, it is an object that stringifies to the name of the option.) For a scalar or array destination, the second argument is the value to be stored...

    And if I get that right something like this:
    use warnings; use strict; use Getopt::Long; GetOptions('test=s{3}'=>\&sub1); sub sub1{ print $_[1]; }
    NOTE: If the is less than what is specified, you get a message of Insufficient arguments for option ....

    UPDATE: * Re^3: Getopt::Long subroutine question

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
      Hi 2teez,

      From my reading of that documentation the my original answer still is correct. Your code calls sub1 3 times (once for each parameter passed on the command line). Yet the OP asked how to have the sub called just once with all parameters in tow.

        Yes, you are right, however, what I intend to answer, is the OP words ..as if the sub was called 3 times..
        That was why I quoted the documentation, that though the sub is called each time an option is encountered, however it could be shown as though those options were gotten once!! Accessing only the the value to be stored, in this case a,b and c NOT like the OP has it test a, test b and test c.

        If you tell me, I'll forget.
        If you show me, I'll remember.
        if you involve me, I'll understand.
        --- Author unknown to me
Re: Getopt::Long subroutine question
by kcott (Abbot) on Jul 23, 2013 at 13:38 UTC

    G'day brassbin,

    If we knew what problem you were attempting to solve with this requirement, you'd probably get better answers.

    If you moved the checking of 3 values (i.e. s{3}) from GetOptions() to sub1() and passed --test a string containing the values, you could do something like this:

    $ perl -Mstrict -Mwarnings -le ' use Getopt::Long; sub sub1 { my ($name, $value) = @_; my $want = 3; my @got = split /\s+/ => $value; die "--$name requires $want values. Got: @got\n" unless @got = += $want; print "$name $_" for @got; } GetOptions( "test=s" => \&sub1 ); ' -- --test 'a b c' test a test b test c

    And with the wrong number of values:

    $ perl -Mstrict -Mwarnings -le ' ... ' -- --test 'a b' --test requires 3 values. Got: a b
    $ perl -Mstrict -Mwarnings -le ' ... ' -- --test 'a b c d' --test requires 3 values. Got: a b c d

    Additional Information Update: You wrote "as if the sub was called 3 times". It's not "as if", that's exactly what's happening. This shows each separate call with the individual arguments highlighted:

    $ perl -Mstrict -Mwarnings -E ' use Getopt::Long; sub sub1 { state $i = 0; ++$i; say "$i: >>>$_<<<" for @_ } GetOptions( "test=s{3}" => \&sub1 ); ' -- --test a b c 1: >>>test<<< 1: >>>a<<< 2: >>>test<<< 2: >>>b<<< 3: >>>test<<< 3: >>>c<<<

    -- Ken

      Thank you all for your help! now i read the documentation again, it does seem to imply that, wish it could be a bit more less stingy in terms of elaborating on parameter-passing to subroutines :-)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1045727]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2014-09-02 03:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (19 votes), past polls