Perl: различие между @_ и $ _ - PullRequest
3 голосов
/ 12 декабря 2011

У меня вопрос со следующим кодом:

#!/usr/bin/perl

use strict;
use warnings;

my %dmax=("dad" => "aaa","asd" => "bbb");
my %dmin=("dad" => "ccc","asd" => "ddd");

&foreach_schleife(\%dmax,\%dmin);

sub foreach_schleife {
        my $concat;
        my $i=0;

        foreach my $keys (sort keys %{$_[0]}) {
                while ($_[$i]) {
                        $concat.="$_[$i]{$keys} ";
                        print $_[$i]{$keys}."\n";
                        $i++;
                }
                $i=0;
                $concat="";
        }
}

Вывод:

   bbb
   ddd
   aaa
   ccc

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

$_[$i]{$keys}."\n";

, а не что-то в этом роде:

$$_[$i]{$keys}."\n";

Почему?Это как-то связано со спецификой переменной @_ / $_?

Ответы [ 3 ]

3 голосов
/ 12 декабря 2011

Причина, по которой вам не нужно разыменовывать $_[0] и $_[1], заключается в том, что $_[$i]{$keys} является допустимым сокращенным обозначением для $_[$i]->{$keys}, когда ваша ссылка находится в массиве или хэше.

$$_[$i]{$keys} не будет работать, потому что он попытается разыменовать специальную переменную $_ в скаляре. Правильный синтаксис: %{$_[$i]}, но тогда вам придется использовать %{$_[$i]}->{$keys}, что является более многословным.

3 голосов
/ 12 декабря 2011

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

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

Чтобы увидеть, что он не является особенным для *_, вы можете попробовать это до цикла:

my @a = @_;

И это во время:

print $a[$i]{$keys}."\n";

Я думаю, что главное в том, что если у вас только есть скалярная ссылка в качестве базы, то требуется хотя бы один ->. Так

my ( $damxr, $dminr ) = @_;

потребуется

$dmaxr->{ $key };
0 голосов
/ 12 декабря 2011

@_ - это массив аргументов подпрограммы, поэтому $_[$index] обращается к элементу в $index

Разыменование полезно только в том случае, если у вас есть ссылки, но @_ не один.

...