Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Get reference to newly-created array

by benizi (Hermit)
on Oct 22, 2007 at 16:14 UTC ( [id://646480]=perlquestion: print w/replies, xml ) Need Help??

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

I use Getopt::Long quite a bit, and I'm pretty fond of this idiom:

use Getopt::Long; GetOptions( 'thing=s' => \(my $thing = ''), 'other=s' => \(my $other = ''), 'flag' => \(my $flag = 0), ) or die 'options'; # usually scripts are for my own use

The one thing that always bugged me about this approach is that I have to treat arrays differently. (I really like defining the scalars the way I've done it above. Makes it easy to add or delete them.) This fails:

use Getopt::Long; GetOptions( 'array=s@' => \(my @array) ) or die 'options';

...because the backslash creates a list of references over its operands. Which, in the case of the newly created array, is the empty list. Is there a way to cleverly get the behavior I want? (a replacement for the "\(my @array)" part that would be equivalent in some sense to "my @array; \@array")

Replies are listed 'Best First'.
Re: Get reference to newly-created array
by ikegami (Patriarch) on Oct 22, 2007 at 16:33 UTC

    [] and do { my @array; \@array }, will both create an array and return a reference to it, but the array will be anonymous. No good.

    You could use prototype trickery to do what you want.

    sub get_array_ref(\@) { $_[0] } GetOptions( 'array=s' => get_array_ref(my @array) ); print("@array\n");

    By the way, it's =s when you pass a reference to an array, and =s@ when you pass a reference to a scalar. That opens up another possibility:

    GetOptions( 'array=s@' => \(my $array) ); print("@$array\n");
      By the way, it's =s when you pass a reference to an array, and =s@ when you pass a reference to a scalar.

      Both seem to work and do what I want. Is there any particular reason to choose one over the other?

      $ cat test-gol.pl #!/usr/bin/perl use Getopt::Long qw/:config pass_through/; my ($array, @array); # option names are: [sa][nw] s=scalar, a=array n=no '@', w=with '@' GetOptions( 'sn=s' => \$array ) or die 'options'; print "Scalar @$array\n"; undef $array; GetOptions( 'sw=s@' => \$array ) or die 'options'; print "Scalar @$array\n"; GetOptions( 'an=s' => \@array ) or die 'options'; print "Array @array\n"; @array = (); GetOptions( 'aw=s@' => \@array ) or die 'options'; print "Array @array\n"; $ perl test-gol.pl --sn one --sn two --sw one --sw two --an one --an t +wo --aw one --aw two Scalar Scalar one two Array one two Array one two

        Both seem to work and do what I want. Is there any particular reason to choose one over the other?

        Yes. One is documented, and the other just happens to work at the moment.

Re: Get reference to newly-created array
by almut (Canon) on Oct 22, 2007 at 18:00 UTC

    As long as you don't need to initialise the array, you should be fine if you simply omit the parentheses. For example

    #!/usr/bin/perl use Getopt::Long; GetOptions( 'thing=s' => \(my $thing = ''), 'flag' => \(my $flag = 0), 'array=s' => \my @array, # no parens # ... ) or die 'options'; print "\@array: @array\n";

    when called as

    $ ./646480.pl -a foo -a bar -a baz

    would print as expected

    @array: foo bar baz

      Thanks, almut. That's exactly what I'm looking for.

Log In?
Username:
Password:

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

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

    No recent polls found