В соответствии с вопросом. Я знаю, что есть значение «0, но истинно», которое истинно в логическом контексте, но false в противном случае, но может возвращать что-то ложное в булевом контексте, но с ненулевым значением (очевидным местом для этого являются статусы возврата, где 0 - успех и что-то else - ошибка).Есть «0, но правда», но есть ли «42, но ложный» в perl?
ответ
номер (для развлечения с 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
"под строгим"? строгий никогда не дает предупреждений; предупреждения дают предупреждения. – ysth
Если не считать пустой список '()' или 'undef'? Не AFAIK, хотя пустые списки могут быть исправлены. –