Как извлечь массив из хэша, который был передан подпрограмме в Perl - PullRequest
1 голос
/ 17 февраля 2012

Я пытаюсь написать подпрограмму, которая принимает в качестве аргумента хэш массивов. Однако, когда я пытаюсь получить один из массивов, я, кажется, получаю размер массива вместо самого массива.

my(%hash) = (  );
$hash{"aaa"} = ["blue", 1];

_subfoo("test", %hash);

sub _subfoo {

    my($test ,%aa) = @_;

    foreach my $name (keys %aa) {
        my @array = @{$aa{$name}};
        print $name. " is ". @array ."\n";
    }
}

Это возвращает 2 вместо (синий, 1), как я ожидал. Есть ли другой способ обработки массивов в хешах в подпрограмме?

Извините, если это слишком просто для переполнения стека, первого постера и новичка в программировании.

Ответы [ 2 ]

10 голосов
/ 17 февраля 2012

Вы помещаете свой массив @array в скалярный контекст прямо здесь:

print $name. " is ". @array ."\n";

Массив в скалярном контексте дает вам количество элементов в массиве, а @array имеет 2 элемента. Попробуйте вместо этого один из них:

print $name . " is " . join(', ', @array) . "\n";
print $name, " is ", @array, "\n";
print "$name is @array\n";

и вы увидите элементы вашего @array. Использование join позволяет вставлять элементы по своему усмотрению; второй оценивает @array в контексте списка и объединяет значения вместе, не разделяя их; третий интерполирует @array, объединяя его элементы вместе с $" (по умолчанию это один пробел).

4 голосов
/ 17 февраля 2012

Поскольку мю слишком коротко, вы упомянули, что вы использовали массив в скалярном контексте, и поэтому он возвратил его длину вместо своих элементов.У меня есть несколько других указателей на ваш код.

Передача аргументов по ссылке иногда является хорошей идеей, когда некоторые из этих аргументов являются массивами или хэшами.Причина этого в том, что массивы и хэши передаются в списки перед передачей в подпрограмму, что делает невозможным что-то подобное:

foo(@bar, @baz);
sub foo {                        # This will not work
    my (@array1, @array2) = @_;  # All the arguments will end up in @array1
    ...
}

Однако это будет работать:

foo(\@bar, \@baz);
sub foo {                  
    my ($aref1, $aref2) = @_;
    ...
}

Вы можете обнаружить, что в вашем случае each - хорошая функция для ваших целей, так как она сделает разыменование массива немного точнее.

foo("test", \%hash);  # note the backslash to pass by reference

sub foo {
    my ($test, $aa) = @_; # note use of scalar $aa to store the reference

    while (my ($key, $value) = each %$aa)) {  # note dereferencing of $aa
        print "$key is @$value\n";            # ...and $value
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...