Подтвердить что ты не робот

Зачем вам $при доступе к массиву и хэш-элементам в Perl?

Так как массивы и хэши могут содержать только скаляры в Perl, почему вы должны использовать $, чтобы сообщить интерпретатору, что это значение является скаляром при доступе к массиву или хэш-элементам? Другими словами, если у вас есть массив @myarray и хеш %myhash, зачем вам нужно:

$x = $myarray[1];
$y = $myhash{'foo'};

вместо того, чтобы делать:

$x = myarray[1];
$y = myhash{'foo'};

Почему вышеупомянутые неоднозначные?

Разве это не был бы незаконный Perl-код, если бы он был чем-то вроде $в этом месте? Например, не все ли следующие недопустимые в Perl?

@var[0];
@var{'key'};
%var[0];
%var{'key'};
4b9b3361

Ответ 1

Ломтики не являются незаконными:

@slice = @myarray[1, 2, 5];
@slice = @myhash{qw/foo bar baz/};

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

Ответ 2

Я только что использовал

my $x = myarray[1];

в программе и, к моему удивлению, вот что произошло, когда я запустил ее:

$ perl foo.pl 
Flying Butt Monkeys!

Это потому, что вся программа выглядит так:

$ cat foo.pl 
#!/usr/bin/env perl

use strict;
use warnings;

sub myarray {
  print "Flying Butt Monkeys!\n";
}

my $x = myarray[1];

Итак, myarray вызывает подпрограмму, передавая ей ссылку на анонимный массив, содержащий один элемент, 1.

Это еще одна причина, по которой вам нужна сигила для доступа к массиву.

Ответ 3

Сигила дает вам тип возврата контейнера. Поэтому, если что-то начинается с @, вы знаете, что он возвращает список. Если он начинается с $, он возвращает скаляр.

Теперь, если после сигилы есть только идентификатор (например, $foo или @foo), тогда это простой доступ к переменной. Если после него следует [, это будет доступ к массиву, если он будет следовать на {, это доступ к хешу.

# variables
$foo
@foo

# accesses
$stuff{blubb} # accesses %stuff, returns a scalar
@stuff{@list} # accesses %stuff, returns an array
$stuff[blubb] # accesses @stuff, returns a scalar
              # (and calls the blubb() function)
@stuff[blubb] # accesses @stuff, returns an array

Некоторые человеческие языки имеют очень похожие понятия.

Однако многие программисты обнаружили, что это запутывает, поэтому Perl 6 использует инвариантную сигил.

В общем компилятор Perl 5 хочет знать во время компиляции, если что-то находится в списке или в скалярном контексте, поэтому без старшей сигилы некоторые термины становятся двусмысленными.

Ответ 4

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

Ответ 5

Это действительный Perl: @var[0]. Это срез массива длиной один. @var[0,1] будет срезом массива длиной два.

@var['key'] недействителен Perl, потому что массивы могут быть проиндексированы только числами и два других (%var[0] and %var['key']) недействительны Perl, поскольку хэш-фрагменты используют {} для индексации хеша.

@var{'key'} и @var{0} являются действительными хэш-срезами. Очевидно, что не принято принимать срезы длины один, но это, безусловно, справедливо.

См. раздел среза perldata perldoc для получения дополнительной информации о разрезе на Perl.

Ответ 6

Я могу думать о том, что

$x = myarray[1];

неоднозначно - что, если вы хотите массив с именем m?

$x = m[1];

Как вы можете сказать, что помимо регулярного выражения?

Другими словами, синтаксис заключается в том, чтобы помочь интерпретатору Perl, ну, интерпретировать!

Ответ 7

В Perl 5 (для изменения в Perl 6) сигила указывает контекст вашего выражения.

  • Вы хотите получить определенный скаляр из хэша, чтобы он $hash{key}.
  • Вы хотите, чтобы значение определенного слота вышло из массива, поэтому оно $array[0].

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

  • Вы хотите, чтобы списки из 1 значения в хеше @hash{key} работали
  • Но также работают более крупные списки, например @hash{qw<key1 key2 ... key_n>}.

  • Вы хотите, чтобы несколько слотов из массива @array[0,3,5..7,$n..$n+5] работали

  • @array[0] - это список размеров 1.

Нет "хэш-контекста", поэтому значение %hash{@keys} и %hash{key} не имеет значения.

Итак, у вас есть "@" + "array[0]" <= > < sigil = context > + < indexing expression > как полное выражение.

Ответ 8

Сигила предоставляет контекст для доступа:

  • $ означает скалярный контекст (скалярный переменная или один элемент хэша или массив)
  • @ означает контекст списка (целый массив или фрагмент хэш или массив)
  • % является целым хешем

Ответ 9

В Perl 5 вам нужны сигилы ($ и @), потому что интерпретация идентификатора простого слова по умолчанию - это вызов подпрограммы (таким образом устраняя необходимость использования и в большинстве случаев).