Perl에서 부울 변수를 어떻게 사용합니까?


220

나는 시도했다 :

$var = false;
$var = FALSE;
$var = False;

이 중 어느 것도 작동하지 않습니다. 오류 메시지가 나타납니다

"엄격한 하위"가 사용되는 동안 Bareword "false"는 허용되지 않습니다.

37
내 책 Learning Perl 로 시작하고 싶을 수도 있습니다 . 올바른 방법 (원숭이, 타자기 및 햄릿 등)이 나올 때까지 무엇을해야할지 추측하는 것보다 쉽습니다. :)
brian d foy 2016 년

답변:


285

Perl에서 다음은 조건부에서 false로 평가됩니다.

0
'0'
undef
''  # Empty scalar
()  # Empty list
('')

나머지는 사실입니다. true또는에 대한 축약어가 없습니다 false.


2
@BlueWaldo : 비교 결과를 스칼라에 비교하고 할당 할 때 cmp 및 <=>를 사용할 수도 있습니다. $ var = $ var1 cmp $ var2; 'cmp'및 '<=>'(숫자 비교에 사용)는 왼쪽 인수가 오른쪽 인수보다 작거나 같거나 큰 경우 -1, 0 또는 1을 반환합니다. 부울이 아니지만 때로는 하나의 인수가 다른 것보다 같거나 작은 지 아닌지 아닌지를 알고 싶을 수도 있습니다.
user118435 2016 년

9
문제 1 : 목록이 참인지 거짓인지 확인할 수 없기 때문에 빈 목록이 거짓이 아닙니다. 스칼라 컨텍스트의 빈 목록은를 반환합니다 undef.
ikegami

4
문제 2 : ('')그리고 ''같은 가치입니다. 빈 문자열로 구성된 요소가있는 목록 (암호가 목록을 만들지 않더라도)을 의미한다고 생각하지만 이미 언급했듯이 목록이 거짓인지 확인하는 것은 불가능합니다.
ikegami

6
문제 3 : 부울 연산자가 오버로드 된 객체도 거짓 일 수 있습니다.
ikegami

15
@eternicode, Perl은 true와 false를 반환해야 할 때 사용하는 두 가지 특정 값을 가지므로 부울뿐만 아니라 true ( !0aka PL_sv_yes) 및 false ( !1aka PL_sv_no)를 갖습니다 . 아니면이 두 가지 값 이외의 다른 것이 진실성을 테스트 할 때마다 펄이 삐걱 거리지 말아야한다고 말하는가? 그것은 완전히 끔찍할 것입니다. 예 : 예방할 것$x ||= $default;
ikegami

71

내가 본 거짓에 대한 가장 완전하고 간결한 정의는 다음과 같습니다.

빈 문자열 또는 문자열로 문자열을 지정하는 0것은 모두 거짓입니다. 그 밖의 모든 것이 사실입니다.

따라서 다음 값은 false입니다.

  • 빈 문자열
  • 숫자 값 0
  • 정의되지 않은 값
  • 위 중 하나를 평가하는 오버로드 된 부울 연산자가있는 오브젝트입니다.
  • 가져 오기에서 위 중 하나로 평가되는 마법 변수입니다.

빈 목록 리터럴은 스칼라 컨텍스트에서 정의되지 않은 값으로 평가되므로 잘못된 것으로 평가됩니다.


"참 제로"에 대한 메모

0문자열 화하는 숫자 는 거짓 이지만 0으로 숫자 화되는 문자열은 반드시 그런 것은 아닙니다. 유일한 잘못된 문자열은 0빈 문자열입니다. 다른 문자열은 0으로 계산 되더라도 사실입니다.

다음은 부울로 true이고 숫자로 0 인 문자열입니다.

  • 경고없이 :
    • "0.0"
    • "0E0"
    • "00"
    • "+0"
    • "-0"
    • " 0"
    • "0\n"
    • ".0"
    • "0."
    • "0 but true"
    • "\t00"
    • "\n0e1"
    • "+0.e-9"
  • 경고와 함께 :
    • Scalar::Util::looks_like_numberfalse 를 반환 하는 모든 문자열 (예를 들어 "abc")

내가 바로 단어를 이해하는 경우 는 true 에서 0으로 캐릭터 라인 화 번호에 해당하는 동안 해야 거짓 또는 (혼동을 방지하기 위해) false로 평가 .
user907860

1
"간결한"정의가 더 이상 설명과 일치하지 않습니다. 고려하십시오 : my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };. 이제 $value"XXX"로 문자열을 지정하지만 거짓으로 부울합니다.
tobyink

1
@tobyink, 간결한 버전은 완벽하지 않으며 내가 찾은 최고입니다. 그것은 모든 것을 포괄하는 것이 아니라 실용적이어야합니다. 에 의해 반환 된 값 bool은에 문자열 화됩니다 0. 또한 일관되지 않은 과부하를 생성하지 않는 것이 좋으며 반환하는 값은 그러한 것으로 간주 될 수 있습니다. (예 : &&는로 최적화 될 수 있으므로 ||일관성이 없으면 문제가있을 수 있습니다.)
ikegami

나는 0x00여기에 덮여 있는지 확실하지 않습니다 .
Zaid

@ Zaid, 당신은 코드 0x00(숫자 값 0) 또는 문자열 0x00( looks_like_number거짓)에 의해 반환되는 값을 의미 합니까? 어느 쪽이든, 이미 덮여 있습니다.
ikegami

59

Perl에는 기본 부울 유형이 없지만 동일한 동작을 얻기 위해 정수 또는 문자열 비교를 사용할 수 있습니다. Alan의 예는 정수 비교를 사용하여 좋은 방법입니다. 여기에 예가 있습니다

my $boolean = 0;
if ( $boolean ) {
    print "$boolean evaluates to true\n";
} else {
    print "$boolean evaluates to false\n";
}

내 프로그램 중 일부에서 한 가지 작업은 상수를 사용하여 동일한 동작을 추가합니다.

#!/usr/bin/perl

use strict;
use warnings;

use constant false => 0;
use constant true  => 1;

my $val1 = true;
my $val2 = false;

print $val1, " && ", $val2;
if ( $val1 && $val2 ) {
    print " evaluates to true.\n";
} else {
    print " evaluates to false.\n";
}

print $val1, " || ", $val2;
if ( $val1 || $val2 ) {
    print " evaluates to true.\n";
} else {
    print " evaluates to false.\n";
}

"상수 사용"으로 표시된 행은 항상 1로 평가되는 true라는 상수와 항상 0으로 평가되는 false라는 상수를 정의합니다. 상수가 Perl에 정의 된 방식으로 인해 다음 코드 행도 실패합니다.

true = 0;
true = false;

오류 메시지는 "스칼라 할당에서 상수를 수정할 수 없습니다"와 같은 내용이어야합니다.

나는 문자열 비교에 관해 당신이 한 의견에서 그것을 보았다. Perl은 스칼라 변수에서 문자열과 숫자 유형을 결합하므로 문자열과 숫자를 비교하기위한 구문이 다릅니다.

my $var1 = "5.0";
my $var2 = "5";

print "using operator eq\n";
if ( $var1 eq $var2 ) {
    print "$var1 and $var2 are equal!\n";
} else {
    print "$var1 and $var2 are not equal!\n";
}

print "using operator ==\n";
if ( $var1 == $var2 ) {
    print "$var1 and $var2 are equal!\n";
} else {
    print "$var1 and $var2 are not equal!\n";
}

이 연산자들의 차이점은 Perl에서 매우 일반적인 혼란의 원인입니다.


5
use warnings;대신#! perl -w
Brad Gilbert

11
그런 식으로 가난한 사람의 매크로로 상수를 사용하는 것은 위험합니다. 이 코드 예제는 동일하지 않습니다 : if ($exitstatus) { exit; }vs. if ($exitstatus == true) { exit; }이는 일반적인 관찰자에게는 분명하지 않을 수 있습니다. (그리고 마지막 예는 프로그래밍 스타일이 좋지 않지만 요점은 아닙니다).
자노

16

나는 추천한다 use boolean;. cpan 에서 부울 모듈 을 설치해야합니다 .


7
인생에서와 마찬가지로 펄에는 많은 진리가 있습니다. 경험이없는 사람들은 다음과 같은 바보 같은 것을 쓰는 것을 좋아 if ($my_true_value == true)합니다. 나의 진실한 진실이있는 척하는 것은 내 경험상 고통의 길과 비효율적 인 코드이다.
tjd

2
펄은 본질 상 철학적이다
ILMostro_7

13

내 즐겨 찾기는 항상

use constant FALSE => 1==0;
use constant TRUE => not FALSE;

내부 표현과는 완전히 독립적입니다.


5
훌륭한. Perl 프로그래밍 언어를 한 손으로 수정했습니다!
Nostalg.io

8

나는 Perl에서 어떤 값이 참인지 거짓인지 잘 설명 하는 튜토리얼 을 보았습니다 . 상태는 다음과 같습니다.

다음 스칼라 값은 거짓으로 간주됩니다.

  • undef -정의되지 않은 값
  • 0 000 또는 0.0으로 쓰더라도 숫자 0
  • '' 빈 문자열
  • '0' 단일 0 자리를 포함하는 문자열

다음을 포함한 다른 모든 스칼라 값은 true입니다.

  • 1 0이 아닌 숫자
  • ' ' 공백이있는 문자열
  • '00' 문자열에서 둘 이상의 0 문자
  • "0\n" 0 다음에 줄 바꿈
  • 'true'
  • 'false' 예, 문자열 'false'조차도 true로 평가됩니다.

Perl true 및 false 에 대해 설명하는 또 다른 좋은 자습서가 있습니다.


6

부울 값에 대해 bobf 가 제공하는 아름다운 설명 : True 또는 False? 빠른 참조 안내서

다른 가치에 대한 진실 테스트

                       Result of the expression when $var is:

Expression          | 1      | '0.0'  | a string | 0     | empty str | undef
--------------------+--------+--------+----------+-------+-----------+-------
if( $var )          | true   | true   | true     | false | false     | false
if( defined $var )  | true   | true   | true     | true  | true      | false
if( $var eq '' )    | false  | false  | false    | false | true      | true
if( $var == 0 )     | false  | true   | true     | true  | true      | true

대답은 좋지 않지만 perlmonks.org의 강력하고 평판이 좋은 출처입니다. 주석과 링크 대신 실제 컨텐츠 를 갖는 것이 좋을 것 입니다. :-/
ILMostro_7

0

다음 파일 접두사를 사용하면 펄 스크립트 eTRUE 및 eFALSE에 추가되며 실제로는 REAL (!) true 및 false입니다 (Java와 동일).

#!/usr/bin/perl
use strict;
use warnings;

use constant { #real true false, compatible with encode_json decode_json for later (we don't want field:false... will be field:0...)
                eTRUE  =>  bless( do{\(my $o = 1)}, 'JSON::PP::Boolean' ),
                eFALSE =>  bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' )
             };

실제로 사용해야하는 데는 몇 가지 이유가 있습니다.

내 이유는 JSON으로 작업 할 때 키 값으로 0과 1을 얻었지만이 해킹은 올바른 값이 스크립트와 함께 유지되도록합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.