2008-09-30 4 views
11

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

все строки myhash должны иметь форму myhash {'foo'} - фигурные скобки для хэшей, а не квадратные. – zigdon 2008-09-30 15:51:29

ответ

16

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

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

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

7

я могу думать так, что

$x = myarray[1]; 

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

$x = m[1]; 

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

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

+0

Это опечатка в исходном вопросе. Поскольку $ y = myhash {foo} и $ y = myarray [1] уже указываются интерпретатору фигурными и квадратными скобками. – zigdon 2008-09-30 15:56:52

+0

Аргумент по-прежнему применяется, но я исправлю его, чтобы обратиться к myarray – 2008-09-30 15:59:11

8

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

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

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

См. the slice section of perldata perldoc для получения дополнительной информации о нарезке в Perl.

11

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

Теперь, если есть только идентификатор после сигилов (как $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 хочет знать во время компиляции, если что-то находится в списке или в скалярном контексте, поэтому без старшей сигилы некоторые термины станут двусмысленными.

+1

Ларри Стена затронула это в этом интервью (видео) .... http://news.oreilly.com/2008/07/larry-wall-at -oscon-open-sourc.html – draegtun 2008-09-30 19:34:50

+0

Что-то, что начинается с @, возвращает список, а не массив. Использование индексировщиков [] не обязательно работает и с массивом. Это может быть список. – 2009-04-21 03:59:27

4

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

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

Это все о Контексте. Понимая, что вы можете лучше видеть Perl. – 2008-09-30 16:48:34

21

Я просто использовал

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.

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

6

В 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]" < => < сигил = контекст> + < выражения индексирования> в качестве полного выражения.

9

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

4

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

 Смежные вопросы

  • Нет связанных вопросов^_^