Поскольку массивы и хэши могут содержать только скаляры в 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'};





Я могу придумать один способ
$x = myarray[1];
неоднозначно - что, если вам нужен массив с именем m?
$x = m[1];
Как вы можете отличить это от совпадения с регулярным выражением?
Другими словами, синтаксис нужен, чтобы помочь интерпретатору Perl, ну, интерпретировать!
Это опечатка в исходном вопросе. Поскольку $ y = myhash {foo} и $ y = myarray [1] уже указаны интерпретатору фигурными и квадратными скобками.
Аргумент все еще применим, но я исправлю его, чтобы он ссылался на myarray
Ломтики не являются незаконными:
@slice = @myarray[1, 2, 5];
@slice = @myhash{qw/foo bar baz/};
И я подозреваю, что это одна из причин, по которой вам нужно указать, хотите ли вы получить одно значение из хеша / массива или нет.
Это действительный Perl: @var[0]. Это кусок массива длиной один. @var[0,1] будет фрагментом массива длиной два.
@var['key'] не является допустимым Perl, потому что массивы могут индексироваться только числами, и
два других (%var[0] and %var['key']) не являются допустимым Perl, потому что срезы хэша используют {} для индексации хэша.
Однако @var{'key'} и @var{0} являются действительными хэш-срезами. Очевидно, что брать срезы длиной один - ненормально, но это определенно верно.
См. секция среза perldata perldoc для получения дополнительной информации о нарезке в Perl.
Сигил дает вам возвращаемый тип контейнера. Итак, если что-то начинается с @, вы знаете, что он возвращает список. Если он начинается с $, он возвращает скаляр.
Теперь, если после сигилы есть только идентификатор (например, $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 хочет знать во время компиляции, находится ли что-то в списке или в скалярном контексте, поэтому без ведущего символа некоторые термины станут неоднозначными.
Ларри Уолл затронул это в интервью (видео) .... news.oreilly.com/2008/07/larry-wall-at-oscon-open-sourc.html
То, что начинается с @, возвращает список, а не массив. Использование индексаторов [] также не обязательно работает с массивом. Это может быть список.
Сигил обеспечивает контекст для доступа:
$ означает скалярный контекст (скалярный
переменная или отдельный элемент хеша или массива)@ означает контекст списка (весь массив или часть
хеш или массив)% - это целый хешВсе дело в контексте. Понимание того, что вы лучше видите Perl.
Сигилы не определяют контекст. рассмотрите $x = @array или $n = keys %hash.
- & - это сигил подпрограммы - * - для сигилла typeglob
Я только что использовал
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.
Это еще одна причина, по которой вам нужен сигил при доступе к массиву.
В Perl 5 (который будет изменен в Perl 6) сигил указывает контекст вашего выражения.
$hash{key}.$array[0].Однако, как указывает zigdon, ломтики допустимы. Они интерпретируют эти выражения в контексте список.
@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> в качестве полного выражения.
К тому же это отказ от Perl4.
Люди уже указали, что у вас могут быть срезы и контексты, но сигилы служат для отделения переменных от всего остального. Вам не обязательно знать все ключевые слова или имена подпрограмм, чтобы выбрать разумное имя переменной. Это одна из самых больших вещей, которые мне не хватает в Perl на других языках.
Понятно. Поэтому, если вы программируете на монохромном терминале и не имеете IDE с подсветкой синтаксиса и используете несколько модулей из CPAN, это увеличивает читаемость кода.
Нет, IDE и подсветка синтаксиса тут ни при чем. Это причины, которые я перечислил в своем ответе.
В Perl 5 вам нужны сигилы ($ и @), потому что по умолчанию идентификатор голого слова интерпретируется как вызов подпрограммы (что устраняет необходимость использования & в большинстве случаев).
все строки myhash должны иметь форму myhash {'foo'} - фигурные скобки для хешей, а не квадратные.