http://www.perlmonks.org?node_id=1011929

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

I would like to pass a named argument with 3 (or more) values using Getopt::Long. To complicate things a bit, the 3 arguments include strings and operators (for an eval call) and I would like to use the argument multiple times. Here is an approach I've considered with a string with comma delimiter:

perl evaluateit.pl --list 'strA,==,100' --list 'strB,>,1000' #!/usr/bin/env perl use strict; use warnings; use Getopt::Long; my %opts = (); my $getoptsresult = GetOptions(\%opts,"list=s@"); my %h = (strA=>100,strB=>999); foreach(@{$opts{list}}){ my @args = split /\,/; my $code = join(' ',$h{$args[0]},$args[1],$args[2]); my $answer = eval($code); print "answer: $answer\n"; #do something with answer }
The complicating factor seems to be that I need to include the --list option many times so defining individual options for the 3 elements isn't practical. There is an example in the Perl 5 v16.2 documentation that looks promising (--coordinates 52.2 16.4 --rgbcolor 255 255 149) but there is a warning that it is experimental and there is no hint as to how to implement it.

Any comments about passing multiple named arguments each with lists of values would be helpful.

Replies are listed 'Best First'.
Re: getopt long, named argument with multiple values
by dasgar (Priest) on Jan 07, 2013 at 04:21 UTC
    but there is a warning that it is experimental and there is no hint as to how to implement it.

    Actually, if you keep reading, the perldoc on Getopt::Long, it tells you how to use that feature.

    From the perldoc:

    This can be accomplished by adding a repeat specifier to the option specification. Repeat specifiers are very similar to the {...} repeat specifiers that can be used with regular expression patterns. For example, the above command line would be handled as follows:

    GetOptions('coordinates=f{1,}' => \@coor, 'rgbcolor=i{3}' => \@color);

    Taking your example code and input, I tested the following code:

    use strict; use warnings; use Getopt::Long; my @list; my $getoptresult = GetOptions('list=s{2}' => \@list); foreach my $item (@list) {print "$item\n";}

    Being on Windows, I had to use a double-quotes instead of single-quotes, but here's how the script was called:

    perl test.pl --list "strA,==,100" "strB,>,1000"

    Here's the output:

    strA,==,100 strB,>,1000

    You'll want to look at the perlre perldoc for more details on what else you can use in "{...} repeat specifiers". In my code, the {1,} is telling Getopt::Long that @list is getting one or more elements.

      Thanks for the help. I am reluctant to use any method in which the documentation says its experimental, but I see now how to use it. Much appreciated.

Re: getopt long, named argument with multiple values
by BrowserUk (Patriarch) on Jan 07, 2013 at 02:23 UTC

    I can't help with the getopt problem, but from a pure 'if I was going to have to use this' perspective:

    • I'd hate to have to type --list again for each field;
    • And a new set of 's for each;
    • And all those comma separators;
    • And unless there are also alternatives to 'strX' part, that's more unnecessary repetition.

    How about: --list '4==100,8>1000,7<=15'. It's easier to type and clearer to read.

    And leaves you the simple task of breaking up the parameter yourself rather than fighting with an undocumented and experimental feature.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
    network sites: