Перебирает ли алмазный оператор Perl немагические массивы (не @ARGV)?

Я не думаю, что следующее должно работать, но оно работает:

$ perl -e '@a = qw/1222 2 3/; while (<@a>) { print $_ ."\n";}'
1222
2
3
$

Насколько я знаю, оператор Perl <> должен работать с файловым дескриптором, шаблонами и т. д., за исключением литерала <> (вместо <FILEHANDLE>), который волшебным образом перебирает @ARGV.

Кто-нибудь знает, должно ли это работать так же, как в моем тесте?


person Fulvio Scapin    schedule 28.10.2009    source источник
comment
Из perlop(1) о ‹› и @ARGV: Вот как это работает: при первом вычислении ‹› проверяется массив @ARGV, и если он пуст, $ARGV[0] устанавливается в -, что при open дает вам стандартный ввод. Затем массив @ARGV обрабатывается как список имен файлов. Я вижу, что что-то подобное происходит с моим @a, хотя не похоже, что это должно происходить с каждым массивом (и я знаю, что foreach или map - лучшие способы обработки массивов). Я все еще хотел бы знать, почему, не копаясь в коде   -  person Fulvio Scapin    schedule 29.10.2009


Ответы (3)


Магия в работе!

Из 'perldoc perlop':

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

Это правило, которое вы запускаете с помощью этого кода. Вот что происходит:

  1. ‹@a> определяется (синтаксически, во время компиляции) как расширение glob
  2. таким образом ‹> превращает @a в строку «1222 2 3» (строковая интерполяция массива)
  3. glob("1222 2 3") в контексте списка возвращает ('1222', '2 ', '3')
person dlowe    schedule 28.10.2009
comment
Итак, я только что встал, но я просто не понимаю #3. - person innaM; 29.10.2009
comment
Поведение таково: если в его аргументе нет метасимволов сопоставления с образцом, glob не беспокоится о переходе в файловую систему. Это может удивить. Это помогает мне думать об этом с точки зрения функциональности glob оболочки, которую glob perl стремится эмулировать: если вы говорите «cat foo», оболочка вызывает «cat» с аргументом «foo», независимо от того, является ли «foo» существуют. Если вы скажете 'cat foo.*', оболочка вызовет 'cat' с переменными аргументами, в зависимости от того, что (если вообще есть) соответствует шаблону. - person dlowe; 29.10.2009

Это вызов glob.

person Sinan Ünür    schedule 28.10.2009

<FH> — это не имя дескриптора файла, а оператор угла, выполняющий операцию линейного ввода над дескриптором. Эта путаница обычно проявляется, когда люди пытаются печатать с помощью оператора угла" - Programming Perl

Итак, в вашем случае массив является дескриптором, что имеет смысл, и, таким образом, оператор повторяет его. Итак, отвечая на ваш вопрос, да, я думаю, что это стандартный (но неясный) Perl. Это неясно, потому что в языке есть более очевидные способы перебора массива.

P.S. Тем не менее, спасибо за это, это будет здорово для соревнований по кодовому гольфу.

person Robert Massaioli    schedule 28.10.2009
comment
Не размещайте ссылки на неавторизованные копии книг. - person Sinan Ünür; 29.10.2009
comment
Упс, я даже не понял. Извините за это. - person Robert Massaioli; 29.10.2009
comment
foreach(@a) такая же короткая и простая, как и while(‹@a›), поэтому она не очень помогает в гольфе кода. - person Jeff B; 29.10.2009
comment
...и for(@a) в точности эквивалентно foreach(@a), но на 4 символа короче, что очень помогает при игре в гольф. - person Dave Sherohman; 29.10.2009