Вот дополнение к другим замечательным ответам, которые вы уже получили.
Не есть не не
Рассмотрим следующий код, который проверяет каждый из операторов Perl «не»:
#!/usr/bin/perl
use strict;
use warnings;
for( '!1', 'not 1', '~0' ) {
my $value = eval;
my $zero_plus = 0 + $value;
print join "\n",
"\nExpression: $_",
"Value: '$value'",
"Defined: " . defined $value,
"Length: " . length($value),
"Plus: " . +$value,
"Plus Zero: '$zero_plus'",
'';
}
print "\nTest addition for a literal null string: ";
print 0+'', "\n";
use Scalar::Util qw(dualvar);
{ # Test a dualvar
my $value = dualvar 0, '';
my $zero_plus = 0+$value;
print join "\n",
"\nExpression: dualvar",
"Value: '$value'",
"Defined: " . defined $value,
"Length: " . length($value),
"Plus: " . +$value,
"Plus Zero: '$zero_plus'",
'';
}
Выполнение этого приводит к следующему. Обратите внимание на предупреждающее сообщение:
Argument "" isn't numeric in addition (+) at test.pl line 21.
Expression: !1
Value: ''
Defined: 1
Length: 0
Plus:
Plus Zero: '0'
Expression: not 1
Value: ''
Defined: 1
Length: 0
Plus:
Plus Zero: '0'
Expression: ~0
Value: '4294967295'
Defined: 1
Length: 10
Plus: 4294967295
Plus Zero: '4294967295'
Test addition for a literal null string: 0
Expression: dualvar
Value: ''
Defined: 1
Length: 0
Plus:
Plus Zero: '0'
Из этого мы узнаем несколько вещей.
Первые два предмета не так уж и интересны:
!1
и not 1
ведут себя в основном одинаково.
- Неудивительно, что
~1
отличается (битовое нет).
Теперь интересный предмет:
- Хотя мы получаем предупреждение для строки 21 (
0+''
), при добавлении 0+!1
.
Требуется два, чтобы запутаться
Что-то подозрительное происходит, и эта подозрительность связана со специальным скалярным контекстом в Perl. В этом случае проводится различие между числовым и строковым контекстами. И возможность создавать переменную, которая имеет разные значения в каждом контексте, или двойную переменную.
Похоже, !1
возвращает двойную переменную, которая возвращает 0 в числовом контексте и пустую строку в строковом контексте.
Тест Dualvar в конце показывает, что самодельный dualvar работает так же, как !1
.
Но это хорошо
Как и многие другие функции Perl, сначала кажется, что двойные переменные не соответствуют ожиданиям и могут вводить в заблуждение. Однако, как и другие функции, при правильном использовании они значительно облегчают жизнь.
Насколько я знаю, дуальная переменная 0
и ''
является единственным определенным значением, которое будет возвращать false во всех скалярных контекстах. Так что это очень разумное возвращаемое значение для !1
. Можно утверждать, что undef
является хорошим ложным результатом, но тогда неинициализированная переменная не отличается от ложного значения. Кроме того, попытки распечатать или добавить результаты логических выражений будут сопровождаться ненужными предупреждениями.
Другой известный дуалвар - $!
или $OS_ERROR
, если вы use English
. В числовой форме вы получите код ошибки, в строковой форме код ошибки переведен для вас.
Это не ничто, это пусто, но это ничто
Итак, в итоге вы ничего не получаете, вы не получаете пустую строку и не получаете ноль.
Вы получаете переменную, которая является одновременно пустой строкой и 0.