Вопрос о приоритете + повторение модификатора - PullRequest
3 голосов
/ 20 февраля 2011

Пожалуйста, не могли бы вы объяснить это очевидно противоречивое поведение для меня:

use strict;
my @a;

print "a" x 2; # this prints: aa
@a = "a" x 2; print @a; # this prints: aa

print ("a") x 2; # this prints: a
@a = ("a") x 2; print @a; # this prints: aa

Разве последний не должен печатать один «а»?

Редактировать: Хорошо, так что теперь для меня это имеет больше смысла: «Двоичный« x »является оператором повторения ... В контексте списка, если левый операнд заключен в скобки или является списком, сформированным из qw / STRING /, он повторяет список." perlop

Это так же ясно, как грязь для меня (двоичный х - зачем использовать слово двоичный? Есть ли динарный Х?) Но в любом случае: @a = ("a") x 2 #, кажется, находится в контексте списка, потому что у нас есть массив в начале - массив не является списком, но он содержит список, поэтому я думаю, что у нас, вероятно, есть контекст списка , (не контекст массива, хотя они могут быть синонимами).

Полагаю, «левый операнд» есть («а»). (Это либо это, либо @a). Perlop не говорит, что на самом деле является операндом, запрос perldoc.perl.org дает «Не найдено совпадений», а поиск в Google дает «В компьютерном программировании операнд - это термин, используемый для описания любого объекта, который способен манипулировать». Например, как массив.

Таким образом, левый операнд может быть заключен в квадратные скобки, поэтому, возможно, он должен «повторить список». Список либо: ("a") x 2 или это: ("a")

Если бы мы повторили ("a") x 2, мы бы получили ("a") x 2 ("a") x 2. Это кажется неправильным.

Если мы введем: print $a[1], мы получим один «a», поэтому «он повторяет список» означает, что Perl превращает ("a") x 2 в ("a", "a"), поэтому мы эффективно получаем @a=("a", "a")

Однако print ("a") x 2 не превращается в ("a", "a"). Это связано с тем, что print является «оператором списка» с высоким приоритетом. Таким образом, мы получаем: (print ("a")) x 2

Массив - это термин, поэтому он также имеет высокий приоритет, но @ a = stuff включает в себя оператор присваивания =, который имеет относительно низкий приоритет. Так что это сильно отличается от печати. ​​

Ответы [ 3 ]

7 голосов
/ 20 февраля 2011

добавьте use warnings; в ваш скрипт, тогда вы получите предупреждений как

print (...) interpreted as function .
Useless use of repeat (x) in void context .

Делай как print (("a") x 2); # это печатает: aa

Как вы упомянули в комментариях, как отформатировать код, я бы сказал, см. Perltidy .

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

Дополнительная информация о Perltidy :

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

Настройка проста и существует огромное количество вариантов. Значения по умолчанию обычно являются хорошей отправной точкой.

Perltidy также можно использовать для генерации цветного вывода HTML вашего кода.

Perltidy поставляется с разумным набором значений по умолчанию; но они могут быть не для вас. К счастью, вы можете использовать tidyview в качестве графического пользовательского интерфейса для предварительного просмотра изменений perltidy в вашем коде и просмотра того, какие параметры подходят вам больше всего. Вы можете загрузить tidyview из CPAN.

Примечание: всегда добавляйте use strict и use warnings в начале ваших сценариев.

4 голосов
/ 20 февраля 2011

Я думаю, что причина вашего странного поведения в том, что команда print для perl - это ожидание списка. Цитата из соответствующей документации :

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

Помещение скобок заставляет его действовать как функция. Подумайте, выполняете ли вы этот тестовый пример:

x("y") x 2;

sub x {
    my $y = shift;
    print "1: $y\n"; #result 1: y
    my $y = shift;
    print "2: $y\n"; #result 2:
}

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

3 голосов
/ 20 февраля 2011

Вас укусила обычная ошибка Perl-анализа.Ваше третье утверждение print ("a") x 2 анализируется как:

(print ("a")) x 2;

Вы можете добавить еще один набор скобок для исправления разбора:

print (("a") x 2);  # prints aa
...