2

I have this 3 lines of code in a sub and I'm trying to write them together on one line only.. but I'm quite lost

    my %p = @_;
    my $arr = $p{name};
    my @a = @$arr;

what's the correct way of doing this?

thank you!

2
  • 2
    my %p = @_; my $arr = $p{name}; my @a = @$arr; :P Commented Feb 24, 2016 at 14:15
  • Most would skip doing my @a = @$arr; as a needless waste of time. Commented Feb 24, 2016 at 15:20

2 Answers 2

3
my %p = @_;

@_ is assumed to contain key-value pairs which are then used to construct the hash %p.

my $arr = $p{name};

The argument list is assumed to have contained something along the lines of name, [1, 2, 3,] so that $p{name} is an reference to an array.

my @a = @$arr;

Dereference that array reference to get the array @.

Here is an invocation that might work with this prelude in a sub:

func(this => 'that', name => [1, 2, 3]);

If you want to reduce the whole prelude to a single statement, you can use:

my @a = @{ { @_ }->{name} };

as in:

#!/usr/bin/env perl

use strict;
use warnings;

use YAML::XS;

func(this => 'that', name => [1, 2, 3]);

sub func {
    my @a = @{ { @_ }->{name} };
    print Dump \@a;
}

Output:

---
- 1
- 2
- 3

If the array pointed to by name is large, and if you do not need a shallow copy, however, it may be better to just stick with references:

my $aref = { @_ }->{ name };
Sign up to request clarification or add additional context in comments.

1 Comment

Right, turning it into a reference works. I didn't think of that.
0

OK so what you're doing is:

  • Assign a list of elements passed to the sub, to a hash.
  • extract a value from that hash (that appears to be an array reference)
  • dereference that into a standalone array.

Now, I'm going to have to make some guesses as to what you're putting in:

#!/usr/bin/perl

use warnings;
use strict;

use Data::Dumper;

sub test {
    my %p = @_;
    my $arr = $p{name};
    my @a = @$arr;
    print Dumper \@a; 
}

my %input = ( fish => [ "value", "another value" ],
              name => [ "more", "less" ], );

test ( %input ); 

So with that in mind:

sub test {
    print join "\n", @{{@_}->{name}},"\n";
}

But actually, I'd suggest what you probably want to do is pass in the hashref in the first place:

#!/usr/bin/perl

use warnings;
use strict;

use Data::Dumper;

sub test {
    my ( $input_hashref ) = @_;
    print Dumper \@{$input_hashref -> {name}};
}

my %input = ( fish => [ "value", "another value" ],
              name => [ "more", "less" ], );
test ( \%input ); 

Also:

  • Don't use single letter variable names. It's bad style.
  • that goes double for a and b because $a and $b are for sorting. (And using @a is confusing as a result).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.