Bram Vanroy
Bram Vanroy

Reputation: 28437

Add Getopt::Long options in a hash, even when using a repeat specifier

Perl's Getopt::Long allows a developer to add their own options to a script. It's also possible to allow multiple values for an option by the use of a repeat specifier, as seen in regular expressions. For example:

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

Furthermore, option values can be stored in a hash, like so:

my %h = ();
GetOptions(\%h, 'length=i');    # will store in $h{length}

What I'm trying to do is, combine these two methods to end up with a hash of my options, even when they have multiple values.

As an example, say I want to allow three options: birthday (three integers), parents (one or two strings), first name (exactly one string). Let's also say that I want to put these values into a hash. I tried the following:

use strict;
use warnings;

use Getopt::Long;
use Data::Dumper;

my %h = ();
GetOptions(\%h, 'bday=i{3}', 'parents=s{1,2}', 'name=s{1}');

print Dumper(\%h);

And tested it, but the output was as follows:

perl optstest.pl --bday 22 3 1986 --parents john mary --name ellen
$VAR1 = {
    'name' => 'ellen',
    'parents' => 'mary',
    'bday' => 1986
};

Only the last value of each option is actually used in the hash. What I would like, though, is:

$VAR1 = {
    'name' => 'ellen',
    'parents' => ['mary', 'john'],
    'bday' => [22, 3, 1986]
};

If 'ellen' would be in an array, or if everything was inside a hash, that'd be fine as well.

Is it not possible to combine these two functionalities of Getopt::Long, i.e. putting options in a hash and using repeat specifiers?

Upvotes: 4

Views: 844

Answers (3)

ikegami
ikegami

Reputation: 385657

If you want an array, you need to give it a reference to an array.

local @ARGV = qw( --x y z );
my %h = ( x => [] );
GetOptions(\%h, 'x=s{2}');
print(Dumper(\%h));

Or you need to specify that you want an array.

local @ARGV = qw( --x y z );
GetOptions(\my %h, 'x=s@{2}');
print(Dumper(\%h));

Output:

$VAR1 = {
          'x' => [
                   'y',
                   'z'
                 ]
        };

Upvotes: 3

palik
palik

Reputation: 2863

use Getopt::Long;
# enable for debugging purposes
# Getopt::Long::Configure("debug");
use Data::Dumper;

my %h = ();
GetOptions(\%h, 'bday=i{3}', 'parents=s@{1,2}', 'name=s@{1}');

print Dumper(\%h);

Is that what you want?

$VAR1 = { 
          'bday' => 1986,
          'name' => [ 
                      'ellen'
                    ],
          'parents' => [ 
                         'john',
                         'mary'
                       ]
        };

Upvotes: 7

Borodin
Borodin

Reputation: 126722

The Options with multiple values section of the documentation that you link to also says this

Warning: What follows is an experimental feature.

It says earlier on

GetOptions (\%h, 'colours=s@'); # will push to @{$h{colours}}

so I guess that it was the author's intent for it to work the same way with repeat specifiers, and that you have found a bug

I suggest that you report it to the Perl 5 Porters using the perlbug utility that is part of the Perl installation

Upvotes: 1

Related Questions