Разыменование значений из массива в объявленные переменные в одной строке - PullRequest
7 голосов
/ 16 марта 2012

Для извлечения аргументов из вызова функции я обычно делаю

use strict;
use warnings;

foo([1,2],[3,4]);

sub foo{
    my ($x, $y) = @_;
    ...
}

В этом примере $ x и $ y теперь являются ссылками на массив каждый. Если я хочу легко использовать переменные внутри этих массивов, я сначала разыменую их.

...
my ($x1, $x2) = @{$x}[0,1];
# ...same for $y

Мне интересно, есть ли способ разыменовать аргументы в @_ (или, действительно, в любом другом массиве) и вернуть их в список объявленных переменных в одну строку?

Ответы [ 3 ]

8 голосов
/ 16 марта 2012
foo ( [1,2], [3,4] );

sub foo {

    my ( $x1, $x2, $y1, $y2 ) = map @$_, @_;

    ...
}

map принимает @_ и разыменовывает каждый из его элементов в массив с помощью операции @$_.

Можно также использовать функции List::Gen deref или d для достижения той же цели.

2 голосов
/ 16 марта 2012

Вот почему у меня unroll:

sub unroll (@) { 
    return map { ref() eq 'ARRAY' ? @$_ : ref() eq 'HASH' ? %$_ : $_ } @_;
}

Так что я могу пойти так:

my ($x1, $y1, $x2, $y2) = unroll @_;

(или)

my ($x1, $y1, $x2, $y2) = &unroll;

намного красивее

map { @$_ } @_[0, 1]

и тому подобное. Плюс, это немного более надежно.

1 голос
/ 16 марта 2012

Я не получаю именно то, что вы хотите, но это нормально:

foo([1,2],[3,4]);
sub foo{
    my ($x1,$x2) = @{$_[0]}[0,1];
    say "x1=$x1 , x2=$x2";
}

выход:

x1=1 , x2=2
...