Что означает «0, но факт» в Perl? - PullRequest
61 голосов
/ 25 сентября 2008

Может кто-нибудь объяснить, что именно означает "0, но true" в Perl? Насколько я понимаю, он равен нулю в целочисленном сравнении, но при использовании в качестве логического значения оценивается как true. Это правильно? Это нормальное поведение языка или это особая строка, интерпретируемая в интерпретаторе как особый случай?

Ответы [ 14 ]

4 голосов
/ 25 сентября 2008

Другой пример «0, но факт»:

Модуль DBI использует «0E0» в качестве возвращаемого значения для запросов UPDATE или DELETE, которые не влияли на какие-либо записи. Он оценивается как true в логическом контексте (указывая на то, что запрос был выполнен правильно) и в 0 в числовом контексте, указывая, что записи не были изменены запросом.

3 голосов
/ 25 сентября 2008

«0, но истина» является строкой, как и любая другая, но из-за синтаксиса perl она может служить полезной цели, а именно возвращать целое число ноль из функции без результата «false» (в глазах perl).

И строка не обязательно должна быть "0, но истина". «0, но false» по-прежнему «true» в логическом смысле.

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

if(x)

for x:        yields:
1             -> true
0             -> false
-1            -> true
"true"        -> true
"false"       -> true
"0 but true"  -> true
int("0 but true") ->false

Результат всего этого вы можете получить:

sub find_x()

и этот код сможет выводить «0» в качестве вывода:

if($x = find_x)
{
   print int($x) . "\n";
}
3 голосов
/ 25 сентября 2008

Если вы хотите написать функцию, которая возвращает либо целочисленное значение, либо false или undef (то есть для случая ошибки), то вы должны следить за нулевым значением , Возвращение его ложно и не должно указывать на условие ошибки, поэтому возвращение «0, но истина» делает возвращаемое значение функции истинным, в то же время возвращая нулевое значение, когда выполняется математика.

2 голосов
/ 07 июня 2012

Строка `` 0 but true '' все еще является специальным случаем:

for arg in "'0 but true'" "1.0*('0 but true')" \
           "1.0*('0 but false')" 0 1 "''" "0.0" \
           "'false'" "'Ja'" "'Nein'" "'Oui'" \
           "'Non'" "'Yes'" "'No'" ;do
    printf "%-32s: %s\n" "$arg" "$(
        perl -we '
            my $ans=eval $ARGV[0];
            $ans=~s/^(Non?|Nein)$//;
            if ($ans) {
                printf "true:  |%s|\n",$ans
            } else {
                printf "false: |%s|", $ans
          };' "$arg"
        )"
    done

дать следующее: (обратите внимание на `` предупреждение ''!)

'0 but true'                    : true:  |0 but true|
1.0*('0 but true')              : false: |0|
Argument "0 but false" isn't numeric in multiplication (*) at (eval 1) line 1.
1.0*('0 but false')             : false: |0|
0                               : false: |0|
1                               : true:  |1|
''                              : false: ||
0.0                             : false: |0|
'false'                         : true:  |false|
'Ja'                            : true:  |Ja|
'Nein'                          : false: ||
'Oui'                           : true:  |Oui|
'Non'                           : false: ||
'Yes'                           : true:  |Yes|
'No'                            : false: ||

... и не забудьте RTFM!

man -P'less +"/0 but [a-z]*"' perlfunc

       ... "fcntl".  Like "ioctl", it maps a 0 return from the system call
           into "0 but true" in Perl.  This string is true in boolean
           context and 0 in numeric context.  It is also exempt from the
           normal -w warnings on improper numeric conversions. ...
...