Perl에서는 undef를 수동으로 변환하는 우아한 방법이 있습니까?

StackOverflow https://stackoverflow.com/questions/1351103

  •  20-09-2019
  •  | 
  •  

문제

이 형식의 조각이 있습니다.

my $a = $some_href->{$code}{'A'}; # a number or undef
my $b = $some_href->{$code}{'B'}; # a number or undef
$a = 0 unless defined($a);
$b = 0 unless defined($b);
my $total = $a + $b;

두 가지 이상의 변수에 관한 것이기 때문에 현실은 훨씬 더 지저분합니다.

내가 정말로 쓰고 싶은 것은 다음과 같습니다.

my $total = $some_href->{$code}{'A'} + $some_href->{$code}{'B'};

그리고 Undef가 0으로 올바르게 평가되었지만 거의 모든 실행에서 이러한 경고를받습니다.

Use of uninitialized value in addition (+) at Stats.pm line 192.

이 메시지를 사라지게하는 가장 좋은 방법은 무엇입니까?

NB : 관련이있는 경우 '엄격한'및 '경고 사용'을 사용합니다.

도움이 되었습니까?

해결책

당신이 사용하는 것이 좋습니다 strict 그리고 warnings. 경고의 목적은 Perl이 의도하지 않을 가능성이있는 행동을 볼 때 경고하는 것입니다. 의도적으로 할 때 경고를 로컬에서 비활성화하는 것은 완벽하게 괜찮습니다. undef 처리됩니다 0 숫자 맥락에서. 정의되지 않은 값이없고 0으로 평가하는 것이 괜찮다면 경고를 비활성화하십시오.

my $total;
{
  no warnings 'uninitialized';
  $total = $some_href->{$code}{A} + $some_href->{$code}{B};
}

참고 : 필요한 경고 만 비활성화하고 가능한 가장 작은 범위에서 그렇게하십시오.

경고를 비활성화하는 데 반대하는 경우 다른 옵션이 있습니다. Perl 5.10 기준으로 사용할 수 있습니다 // (정의 또는) 연산자는 기본값을 설정합니다. 그 전에는 사람들이 종종 사용합니다 || (논리적 또는) 그러나 그것은 거짓으로 평가하는 값에 대해 잘못된 일을 할 수 있습니다. Pre-5.10 버전의 기본값을 기본값으로하는 강력한 방법은 PERL이 있는지 확인하는 것입니다. defined.

$x = $y // 42;             # 5.10+
$x = $y || 42;             # < 5.10 (fragile)
$x = defined $y ? $y : 42; # < 5.10 (robust)

다른 팁

"비 초기"경고를 잠시 끄울 수 있습니다.

my $a;
my $b = 1;
{
    no warnings 'uninitialized';
    my $c = $a+$b; # no warning
}
my $c = $a+$b; # warning

또는 단락을 0으로 단락시킬 수 있습니다.

my $d = ($a||0)+$b; # no warning

그래도 나에게 아주 좋아 보이지 않습니다.

추가 할 때 Undefs를 걸러 내십시오.

use List::Util 'sum';

my $total = sum (0, grep {defined} $some_href->{$code}{'A'}, $some_href->{$code}{'B'});

또는

use List::Util 'sum';

my $total = sum (0, grep {defined} map {$some_href->{$code}{$_}} 'A', 'B');
my $a = $some_href->{$code}{'A'} || 0;
my $b = $some_href->{$code}{'B'} || 0;
my $total = $a + $b;

이 경우 폴백 값으로 인해 잘못된 값을 정의되지 않은 값과 동일하게 처리해도 괜찮습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top