2015-03-22 5 views
0

Я запутался с приоритетом оператора в Perl. У меня есть выражение, как:Переопределение приоритета оператора

$a || $b ? join ",", @$b : "" 

Я думал, что Perl будет создать контекст списка:

my $result = $a || ($b ? join ",", @$b : ""); 
# I thought (...) would create a list context and make result = 1, 
# but $result is correctly set to the join of @$b 
# Why does it not create list context? 
+0

Просто из любопытства, чего именно вы пытаетесь достичь? Связано ли это с вашим предыдущим вопросом об использовании '@ ARGV' или' STDIN'? Более конкретный пример был бы приятным. В общем, я бы использовал только условный оператор для очень простых случаев, так как немного умнее анализировать, чем простой 'if' /' else'. – ThisSuitIsBlackNot

+0

@thissuitisblacknot хорошо, что они не совсем связаны, но это проблемы, которые у меня были в одном проекте.если иначе всегда есть универсальное решение, но я просто хочу знать некоторые грязные хаки perl – texasbruce

ответ

2

Из раздела о контексте в perldoc perldata:

Назначение немного особенного в том, что он использует свой левый аргумент для определения контекста для правильного аргумента. Присвоение скаляру оценивает правую часть в скалярном контексте, тогда как присвоение массиву или хешу оценивает правую сторону в контексте списка. Присвоение списку (или срезу, который является только списком) также оценивает правую часть в контексте списка.

(курсив)

И от perldoc perlop:

условного оператора

[...]

Скалярные или контекст списка распространяется вниз в 2 или 3-й аргумент, в зависимости от того, что выбрано.

$a = $ok ? $b : $c; # get a scalar 
@a = $ok ? @b : @c; # get an array 
$a = $ok ? @b : @c; # oops, that's just a count! 

Что касается старшинства, || имеет более высокий приоритет, чем условный оператор, так

my $result = $foo || $bar ? 0 : 1; 

эквивалентно

my $result = ($foo || $bar) ? 0 : 1; 

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

Опять же, в

my $result = $foo || ($bar ? 0 : 1); 

круглые скобки не создают контекст списка. С ||

Скаляр или контекст списка распространяется до правого операнда, если он оценивается.

так ($bar ? 0 : 1) оценивается в скалярном контексте (при условии $foo является истинным значением, а если нет, || короткого замыкания и РИТ не вычисляется вовсе).

+0

Скобки не создают контекст списка? Что они делают? – texasbruce

+0

@texasbruce В этом случае скобки просто используются для группировки; они просто влияют на приоритет. Кроме того, не путайте значения * списка * со списком * context *. См. [Конструкторы значений списка] (http://perldoc.perl.org/perldata.html#List-value-constructors) в 'perldoc perldata'. – ThisSuitIsBlackNot

+1

@texasbruce Также см. Ответ ikegami на «Может ли пустой список быть в скалярном контексте?»] (Http://stackoverflow.com/a/6970812/176646) и [Скалярный список операторов назначения списков] (http: // www.perlmonks.org/?node_id=790129) учебник по PerlMonks. Это распространенное заблуждение, что круглые скобки создают список; они этого не делают. Посты, которые я связывал, объясняют два частых источника путаницы: 'my $ foo =();' (''() 'на самом деле не список, хотя иногда он называется нулевым списком или пустым списком); и 'my ($ foo) = ...' – ThisSuitIsBlackNot

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