문제

Perl에서 "0이지만 true"라는 문자열이 정확히 무엇을 의미하는지 설명할 수 있는 사람이 있습니까?내가 아는 한, 정수 비교에서는 0과 같지만 부울로 사용하면 true로 평가됩니다.이 올바른지?이것은 언어의 정상적인 동작입니까, 아니면 인터프리터에서 특별한 경우로 처리되는 특수 문자열입니까?

도움이 되었습니까?

해결책

언어의 정상적인 행동입니다. 인용 perlsyn 맨 페이지 :

0, 줄 '0' 그리고 "", 빈 목록 (), 그리고 undef부울 맥락에서 모두 거짓입니다. 다른 모든 값은 사실입니다. 진정한 가치의 부정 ! 또는 not 특별한 허위 값을 반환합니다. 문자열로 평가되면 처리됩니다 "", 그러나 숫자로서, 그것은 0.

이 때문에 돌아올 수있는 방법이 필요합니다. 0 반품을 기대하는 시스템 호출에서 0 (성공적인) 반환 값으로, 실제로 오 탐지를 반환하여 실패 사건을 알리는 방법을 남기십시오. "0 but true" 그 목적을 제공합니다.

다른 팁

Perl 코어에서 하드 코딩되어 숫자로 취급하기 때문입니다. 이것은 Perl의 컨벤션을 만드는 해킹이며 ioctl의 규칙은 함께 재생됩니다. ~에서 perldoc -f ioctl:

반환 값 ioctl (그리고 fcntl) 다음과 같다:

if OS returns:      then Perl returns:

    -1              undefined value
     0              string "0 but true"
anything else       that number

따라서 PERL은 성공에 맞게 반환되고 실패에 대한 거짓이지만 운영 체제가 반환 한 실제 값을 쉽게 결정할 수 있습니다.

$retval = ioctl(...) || -1;
printf "System returned %d\n", $retval;

특별한 문자열 "0 but true" 면제됩니다 -w 부적절한 숫자 전환에 대한 불만.

다른 사람들의 말에 추가로 "0 but true" 숫자 맥락에서는 경고하지 않는다는 점에서 특별한 입장이 있습니다.

$ perl -wle 'print "0 but true" + 3'
3
$ perl -wle 'print "0 but crazy" + 3'
Argument "0 but crazy" isn't numeric in addition (+) at -e line 1.
3

가치 0 but true Perl의 특별한 경우입니다.비록 당신의 단순한 인간의 눈에는 그것이 숫자처럼 보이지 않을지라도, 현명하고 Perl이 아는 모든 사람들은 이것이 정말로 숫자라는 것을 이해합니다.

이는 Perl 서브루틴이 0 값을 반환할 때 루틴이 실패했거나 잘못된 값을 반환했다고 가정한다는 사실과 관련이 있습니다.

두 숫자의 합을 반환하는 서브루틴이 있다고 상상해 보세요.

die "You can only add two numbers\n" if (not add(3, -2));
die "You can only add two numbers\n" if (not add("cow", "dog"));
die "You can only add two numbers\n" if (not add(3, -3));

서브루틴이 다음을 반환하기 때문에 첫 번째 문은 죽지 않습니다. 1.좋아요.서브루틴이 추가할 수 없기 때문에 두 번째 명령문은 종료됩니다. 암소 에게 .

그리고 세 번째 진술은요?

흠, 추가해도 돼요 3 에게 -3.나는 단지 얻는다 0, 하지만 내 프로그램은 종료됩니다. add 서브루틴이 작동했습니다!

이 문제를 해결하기 위해 Perl은 다음을 고려합니다. 0 but true 숫자가 되십시오.만약 내 추가하다 서브루틴은 단순히 반환하는 것이 아니라 0, 하지만 0이지만 사실이다, 세 번째 진술이 작동합니다.

하지만 0이지만 사실이다 숫자 0?다음을 시도해보세요:

my $value = "0 but true";
print qq(Add 1,000,000 to it: ) . (1_000_000 + $value) . "\n";
print "Multiply it by 1,000,000: " . 1_000_000 * $value . "\n";

응, 0이야!

그만큼 색인 서브루틴은 Perl의 아주 오래된 부분이며 Perl의 개념 이전에 존재했습니다. 0이지만 사실이다 주위에 있었다.문자열에 있는 하위 문자열의 위치를 ​​반환한다고 가정합니다.

index("barfoo", "foo");   #This returns 3
index("barfoo", "bar");   #This returns 0
index("barfoo", "fu");    #This returns ...uh...

마지막 명령문은 -1.내가 이 작업을 수행했다면 이는 다음을 의미합니다.

if ($position = index($string, $substring)) {
   print "It worked!\n";
}
else {
   print "If failed!\n";
}

일반적으로 표준 기능을 사용하는 것처럼 작동하지 않습니다.두 번째 문장에서처럼 "barfoo"와 "bar"를 사용했다면, else 절이 실행되지만 세 번째에서처럼 "barfoo"와 "fu"를 사용하면 if 절이 실행됩니다.내가 원하는 것이 아닙니다.

그러나 만약 index 서브루틴이 반환됨 0이지만 사실이다 두 번째 진술과 undef 세 번째 진술에 대해서는 내 if/else 조항이 작동했을 것입니다.

문자열도 볼 수 있습니다 Perl 코드에 사용 된 "0E0", 그리고 그것은 같은 것을 의미합니다. 여기서 0e0은 단지 지수 표기법으로 기록 된 0을 의미합니다. 그러나 Perl은 "0", ''또는 undef 만 false로만 간주하기 때문에 부울 맥락에서 True로 평가됩니다.

Perl의 소스 코드, 특히 numeric.c의 perl_grok_number_flags.

이 코드를 읽는 것은 문자열 "인피니티"(Case Insensitive)가 Look_like_number 테스트도 전달한다는 것을 발견했습니다. 나는 그것을 알지 못했다.

정수 컨텍스트에서는 0 (문자열의 시작 부분에서 숫자 부분)으로 평가하고 0으로 평가합니다. 스칼라 컨텍스트에서는 비어 있지 않은 값이므로 사실입니다.

  • if (int("0 but true")) { print "zero"; }

    (출력 없음)

  • if ("0 but true") { print "true"; }

    (진실 인쇄)

0 Perl (및 C와 관련된 다른 언어)에서 False를 의미합니다. 대부분의 경우, 그것은 합리적인 행동입니다. 다른 언어 (LUA)는 치료합니다 0 진실하고 다른 토큰을 제공합니다 (종종 또는 거짓) 비 트루 값을 나타내는 것.

Perl Way가 잘 작동하지 않는 경우 중 하나는 숫자를 반환하려고하거나 어떤 이유로 기능이 실패하면 잘못된 값입니다. 예를 들어, 파일에서 줄을 읽고 라인의 문자 수를 반환하는 함수를 작성하는 경우. 함수의 일반적인 사용법은 다음과 같습니다.

while($c = characters_in_line($file)){
    ...
};

특정 줄의 문자 수가 0이면 동안 루프는 파일 끝 전에 끝납니다. 그래서 문자 _in_line 기능은 특수한 경우 0 자 및 반환해야합니다 '0이지만 진실' 대신에. 그렇게하면 기능이 의도 한대로 작동합니다. 동안 루프는 숫자로 사용되면 정답을 반환합니다.

이것은 언어의 일부가 내장되어 있지 않습니다. 오히려 문자열을 숫자로 해석하는 Perl의 능력을 활용합니다. 따라서 다른 찌르기는 때때로 대신 사용됩니다. DBI 용도 "0E0", 예를 들어. 숫자 맥락에서 평가되면 돌아옵니다 0, 그러나 부울 맥락에서 거짓.

거짓 인 것들 :

  • "".
  • "0".
  • 그것들에게 소멸시키는 것들.

"0 but true" 그 중 하나가 아니므로 거짓이 아닙니다.

또한 Perl이 반환됩니다 "0 but true" 0을 반환하더라도 함수가 성공했음을 알리기 위해 숫자가 예상되는 경우. Sysseek 그러한 기능의 예입니다. 값은 숫자로 사용될 것으로 예상되므로 Perl은 숫자로 간주하도록 코딩됩니다. 결과적으로 숫자로 사용될 때 경고는 발행되지 않으며 looks_like_number("0 but true") 진실을 반환합니다.

다른 "진정한 제로"는 찾을 수 있습니다 http://www.perlmonks.org/?node_id=464548.

"0이지만 true"의 또 다른 예 :

DBI 모듈은 "0E0"을 업데이트 또는 삭제 쿼리의 리턴 값으로 사용합니다. 부울 컨텍스트 (쿼리가 올바르게 실행되었음을 나타내는)에서 TRUE로 평가하고 쿼리에 의해 레코드가 변경되지 않았 음을 나타내는 숫자 컨텍스트에서 0으로 평가됩니다.

방금 문자열 "0이지만 true"가 해석자에 실제로 내장되어 있다는 증거를 발견했습니다.

$ strings /usr/lib/perl5/5.10.0/linux/CORE/libperl.so | grep -i true
Perl_sv_true
%-p did not return a true value
0 but true
0 but true

정수 값을 반환하는 함수를 작성하려면 거짓 또는 undef (즉, 오류 케이스의 경우) 값 0을 조심해야합니다. 반환하는 것은 거짓이므로 오류 조건을 표시하지 않아야하므로 "0이지만 true"를 반환하면 수학이 완료 될 때 값이 0을 다시 전달하는 동안 함수 리턴 값이 true를 반환합니다.

"0이지만 true"는 다른 문자열이지만 Perl의 구문으로 인해 유용한 목적, 즉 결과가 "false"(Perl의 눈)가없는 함수에서 정수 0을 반환 할 수 있습니다.

그리고 문자열은 "0이지만 true"일 필요는 없습니다. "0이지만 거짓"은 부울 의미에서 여전히 "참"입니다.

고려하다:

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";
}

문자열``0이지만 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. ...
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top