В Perl, какая разница между "if defined $count" и "if $count"?

У меня есть следующий script:

#!/usr/bin/perl
use warnings;
use strict;

my $count = 0; 
my ( @first , @second , @third );

while ($count <= 7){

    push ( @first , $count);
    push ( @second , $count) if defined $count;
    push ( @third , $count) if $count;
    $count++;

}

print "first: @first\n";
print "second: @second\n";
print "third: @third\n";

Это приводит к следующему выводу:

first: 0 1 2 3 4 5 6 7
second: 0 1 2 3 4 5 6 7
third: 1 2 3 4 5 6 7

В чем разница между помещением if defined $count vs. if $count, кроме последнего метода, не будет добавлять нуль в массив? Я искал perldocs, но не смог найти ответ.

Ответ 1

Правда и ложность в perlsyn объясняет, какие значения считаются ложными в булевом контексте:

Число 0, строки '0' и '', пустым списком () и undef являются все false в булевом контексте. Все остальные значения верны.

undef - это значение переменной, которая никогда не была инициализирована (или была reset с помощью функции undef). Функция defined возвращает true, если значение выражения не равно undef.

if $count является ложным, если $count - это число 0, строка '0', пустая строка, undef или объект, который был перегружен, чтобы вернуть одну из этих вещей при использовании в булевом контексте. В противном случае это правда. (Пустой список не может быть сохранен в скалярной переменной.)

if defined $count является ложным, только если $count - undef.

Ответ 2

если вы видите документацию defined в perldoc, то вы обнаружите, что

  • Возвращает логическое значение, указывающее имеет ли EXPR значение другое чем значение undefined undef. Если EXPR отсутствует, $_ проверяется.

  • Простой булевский тест не будет отличить от undef, zero, пустая строка и "0", которые все равно false.

что означает,

push ( @second , 'undef') if defined $count; 

когда $count = 0, тогда он определяется, потому что 0 отличается от undef, а определяется возвращает true, но в этом случае push ( @third , 'undef') if $count; if condition не удается, поэтому не нажимая 0 в массив.

Ответ 3

if решает запустить свой блок (или один оператор), посмотрев на значение выражения, которое вы ему даете:

 if( EXPR ) { ... }

Если это выражение истинно, он выполняет свой блок. Если это выражение ложно, это не так.

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

Итак, удалив эту часть вашего вопроса, вы останетесь с "Какая разница между defined $count и $count". Ну, это возвращаемое значение для defined, а другое - любое значение, хранящееся в $count.

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

Вы говорите, что искали в документации, но я не уверен, где вы посмотрели. Если вы хотите найти встроенную функцию, вы можете использовать переключатель perldoc -f:

 $ perldoc -f defined

Если вы хотите прочитать о синтаксисе Perl для таких вещей, как if, то в perlsyn.

У меня есть руководство для начинающих к документам Perl в документации документации Perl.

Ответ 4

Тестирование предикатов defined для определения того, определена ли переменная ($count в этом случае). В коде, который вы написали, он всегда будет определен внутри цикла, потому что он всегда получил некоторое значение.

Если бы вы добавили:

undef $count;
push ( @first , 'undef'); 
push ( @second , 'undef') if defined $count; 
push ( @third , 'undef') if $count; 

после цикла, вы увидите разницу. (Обратите внимание, что я изменил код, чтобы добавить литерал 'undef' вместо $count, потому что вы получите вводящие в заблуждение эффекты от добавления фактического значения undef.

Ответ 5

Как любое fule kno, "Число 0, строки" 0 "и" ", пустой список() и undef" не должны равняться false, поскольку они не являются логическими по своей природе. Написание кода, который опирается на это извращение, в то время как технически правильно, вводит в заблуждение и должен быть сильно обескуражен. Как и сорняки и сиськи.

Ответ 6

Как я его читал.

if $count действует только тогда, когда $count оценивает != 0, поэтому третий массив не имеет в нем 0.

if defined $count проверяет, был ли создан $count в качестве скаляра, и поскольку у вас есть $count scalar, он будет таким же, как и первый.

Ответ 7

if 0 = false
if _ = false