2015-03-27 2 views
7

Посмотрите на документацию для Reading Excel, есть заявление, которое я действительно не понимаю.Что такое || = in perl for?

Может кто-нибудь объяснить, что $sheet -> {MaxRow} ||= $sheet -> {MinRow}; делает?

Я получаю этот оператор присваивания. Однако я не понимаю, как должно работать ||?

ответ

12
$sheet -> {MaxRow} ||= $sheet -> {MinRow}; 

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

$sheet -> {MaxRow} = ($sheet -> {MaxRow} || $sheet -> {MinRow}); 

Местный оператор ИЛИ вычисляет второй операнд, только если первый из них является ложным. Итак, MaxRow получит значение MinRow, если MaxRow равно 0 (возможно, первая итерация).

6

Оператор ||= является логическим-ИЛИ-назначать. Он похож на +=, который является добавочным. Он вычисляет логический ИЛИ LHS и RHS, а затем присваивает результат LHS, поэтому он должен быть действительным значением lvalue.

Другими словами, так же, как

$a += 3; 

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

$a = $a+3; 

мы можем сказать, что

$a ||= 1; 

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

$a = $a||1; 

Теперь, что касается утверждения, которое вы упомянули в своем вопросе, там немного больше происходит, чем в моем примере выше. В вашем заявлении LHS - это не просто простой токен переменной, а переменный токен, который обрабатывается как хеш-ссылка ($sheet) и разыменовывается для получения значения, которое вводится с помощью строки 'MaxRow'. RHS также представляет собой операцию разыменования хэша на $sheet, но ключ которого равен 'MinRow'. Но поведение такое же; мы можем сказать, что

$sheet->{'MaxRow'} ||= $sheet->{'MinRow'}; 

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

$sheet->{'MaxRow'} = $sheet->{'MaxRow'}||$sheet->{'MinRow'}; 

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

более подробную информацию о логической операции ИЛИ, см http://en.wikipedia.org/wiki/Logical_disjunction, так и для Perl-специфической информации, см http://perldoc.perl.org/perlop.html#C-style-Logical-Or (для || и //) и http://perldoc.perl.org/perlop.html#Logical-or-and-Exclusive-Or (для or). Наиболее релевантная цитата из документации Perl по адресу ||:

Двоичный "||" выполняет операцию логического ИЛИ короткого замыкания. То есть, если левый операнд истинен, правый операнд даже не оценивается. Скаляр или контекст списка распространяется до правого операнда, если он оценивается.

Это не совсем объясняет это; в случае, когда LHS оценивает правдоподобное значение (см. ниже для определения), тогда возвращаемое значение операции || является значением LHS, в противном случае это значение RHS.

В Perl, логические значения, как правило, представлены 0 (или иногда '' или undef) для ложных и 1 для истинно.Однако, более конкретно, любое значение, которое не является одним из трех вышеперечисленных ложных значений, трактуется как истинный, и иногда программисты ссылаются на это различие, используя неофициальные термины «правдивость» и «ложь». IOW, 0, '' и undef являются фальшивками, а все остальное правдиво. См. http://www.perlmonks.org/?node=what%20is%20true%20and%20false%20in%20Perl%3F для более подробной информации.

+0

Есть ли версия этого, которая сначала оценивает правую сторону? Я ищу ярлык, который означает '$ a = $ b, если $ b'. – felwithe

+0

@felwithe Это зависит от того, что вы хотите совершить с '$ a', в случае, если условие RHS оценивается как ложное. Если вы хотите сохранить существующее значение '$ a', то ваш оператор присваивания работает как есть, так как оператор infix' if' работает так, как вы его написали, и будет препятствовать тому, чтобы назначение выполнялось вообще, если его условное является ложным. Если вы хотите значение по умолчанию, например 'undef', то я думаю, что ответ на ваш вопрос технически нет, но вы можете написать подпрограмму для этого:' sub if2 {return $ _ [1]? $ _ [0]: undef; } ', а затем для вызова:' $ a = if2 $ b, $ b; '. – bgoldst

+0

Привет ... Я имею в виду, как будто это говорит. Я просто подумал, может быть, был замечательный ярлык Перла, о котором я не знал. – felwithe