2013-04-18 1 views
3

В соответствии с вопросом. Я знаю, что есть значение «0, но истинно», которое истинно в логическом контексте, но false в противном случае, но может возвращать что-то ложное в булевом контексте, но с ненулевым значением (очевидным местом для этого являются статусы возврата, где 0 - успех и что-то else - ошибка).Есть «0, но правда», но есть ли «42, но ложный» в perl?

+0

Если не считать пустой список '()' или 'undef'? Не AFAIK, хотя пустые списки могут быть исправлены. –

ответ

8

номер (для развлечения с dualvars и перегруженных объектов)

truthiness скаляра Perl зависит прежде всего от значения строки. Если нет строкового значения, будет использоваться числовое поле.

Ложные значения: undef, "", 0, и, чтобы избежать проблем при тестировании stringification первых: "0".

Не все, что численно равно нулю, равно false: "0E0" истинно, и тем более самодокументирующийся "0 but true". Последний имеет специальную оболочку, чтобы избежать нечисловых предупреждений.

Однако введите dualvars. Числовое и строковое поле скаляра не должно синхронизироваться. Общим двойным символом является переменная $!, которая является errno в числовом контексте, но строка ошибки, содержащая причину в виде строки. Таким образом, можно было бы создать двойную диаграмму с числовым значением 42 и строковое значение "", которое будет оцениваться как ложное.

use Scalar::Util qw/dualvar/; 

my $x = dualvar 42, ""; 
say $x; # empty string 
say 0+$x; # force numeric: 42 
say $x ? 1 : 0; # 0 

А потом перегруженные объекты. Экземпляры следующий класс будет stringify красиво, но по-прежнему вычисляться ложной в логическом контексте:

package FalseString; 
sub new { 
    my ($class, $str) = @_; 
    bless \$str => $class; 
} 
use overload 
    '""' => sub { ${shift()} }, 
    'bool' => sub { 0 }; 

Тест:

my $s = FalseString->new("foo"); 
say $s; 
say $s ? "true" : "false"; 

Печать

foo 
false 
+1

"под строгим"? строгий никогда не дает предупреждений; предупреждения дают предупреждения. – ysth