% $ Var разыменовывает хеш Perl? - PullRequest
8 голосов
/ 18 февраля 2009

Я отправляю подпрограмму хэш и извлекаю ее с помощью my($arg_ref) = @_;

Но что именно такое %$arg_ref? %$ разыменовывает хеш?

Ответы [ 5 ]

19 голосов
/ 18 февраля 2009

$arg_ref - это скаляр, поскольку он использует символ $. Предположительно, он содержит ссылку на хеш. Так что да, %$arg_ref задерживает эту хэш-ссылку. Еще один способ написать это %{$arg_ref}. Это делает код более понятным, хотя и более подробным.

Цитировать с perldata(1):

 Scalar values are always named with '$', even when referring
 to a scalar that is part of an array or a hash.  The '$'
 symbol works semantically like the English word "the" in
 that it indicates a single value is expected.

     $days               # the simple scalar value "days"
     $days[28]           # the 29th element of array @days
     $days{'Feb'}        # the 'Feb' value from hash %days
     $#days              # the last index of array @days

Итак, ваш пример будет:

     %$arg_ref           # hash dereferenced from the value "arg_ref"

my($arg_ref) = @_; захватывает первый элемент в стеке аргументов функции и помещает его в локальную переменную с именем $arg_ref. Вызывающий отвечает за передачу хеш-ссылки. Более канонический способ написать это:

my $arg_ref = shift;

Чтобы создать ссылку на хеш, вы можете начать с хеша:

some_sub(\%hash);

Или вы можете создать его с анонимной ссылкой на хеш:

some_sub({pi => 3.14, C => 4}); # Pi is a gross approximation.
7 голосов
/ 19 февраля 2009

Вместо того, чтобы разыменовывать весь хэш таким образом, вы можете получить отдельные элементы с помощью

$arg_ref->{key}
4 голосов
/ 19 февраля 2009

Хорошее краткое введение в ссылки (создание и использование их) в Perl - perldoc perfeftut. Вы также можете прочитать его онлайн (или получить в формате PDF). (В нем говорится больше о ссылках в сложных структурах данных, чем о входных и выходных подпрограммах, но синтаксис тот же.)

2 голосов
/ 19 февраля 2009
my %hash = ( fred => 'wilma',
             barney => 'betty');
my $hashref = \%hash;
my $freds_wife = $hashref->{fred};
my %hash_copy = %$hash # or %{$hash} as noted above.

Так, в чем смысл гибкости синтаксиса? Давайте попробуем это:

my %flintstones = ( fred => { wife => 'wilma',
                              kids => ['pebbles'],
                              pets => ['dino'],
                            }
                    barney => { # etc ... }
                  );

На самом деле для таких глубоких структур данных часто удобнее начинать с ссылки:

my $flintstones = { fred => { wife => 'Wilma',
                               kids => ['Pebbles'],
                               pets => ['Dino'],
                              },
                   };

ОК, Фред получает нового питомца, «Велоцираптор»

push @{$flintstones->{fred}->{pets}}, 'Velociraptor';

Сколько домашних животных у Фреда?

scalar @ {flintstones -> {fred} -> {pets}}

Давайте покормить их ...

for my $pet ( @ {flintstones->{fred}->{pets} } ) {
    feed($pet)
}

и так далее. Сначала суп с фигурными скобками может показаться немного пугающим, но в конце концов с ними довольно легко справиться, если вы будете последовательны в том, как вы справляетесь с ними.

1 голос
/ 19 февраля 2009

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

sub foo {
  my ($arg_ref) = @_;
  # do something with $arg_ref->{keys}
}

может быть излишним, в отличие от простой распаковки @ _

sub bar {
  my ($a, $b, $c) = @_;
  return $c / ( $a * $b );
}

В зависимости от сложности списка аргументов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...