문제

다음과 유사한 Perl 코드가 있습니다.

# -- start --

my $res;

# run query to fetch IPv6 resources
while( my $row = $org_ip6_res->fetchrow_arrayref )
{
    if( $row->[4] =~ /PA/ ) {
        $res->{ipv6}{pa}{$row->[2]}++;
    } elsif( $row->[4] eq 'PI' ) {
        $res->{ipv6}{pi}{$row->[2]}++;
    }
}

# -- stop --

어떤 시점에도 $res 쿼리 결과를 반복하기 전에 설정했지만 코드는 잘 실행됩니다.

각 값 전에 인쇄 명세서를 넣을 때 두 경우 모두 공백이 발생하지만 증분 증분이 적용된 후 인쇄 문이 오면 조직의 IPv6 리소스 수에 따라> = 1의 값을 얻습니다.

내 질문은 Perl의 비 초기 해시 키를 자동으로 0 인 것을 의미하는 것입니다.

초보자 질문으로 만나면 죄송하지만 그런 구조에 익숙하지 않습니다. $hashref->{foo}->{bar}++값이 아직 명시 적으로 할당되지 않은 경우 $hashref->{foo}->{bar}. 미리 감사드립니다!

도움이 되었습니까?

해결책

값은 자동으로 0이 아닙니다. 값은 처음에는 정의되지 않았습니다. 그러나 숫자처럼 취급하면 (예 : 적용 ++ 그것에), 그 다음 Perl은 그것을 0처럼 취급합니다. 끈처럼 취급하면 (예 : 적용 . 그 다음), Perl은 그것을 빈 줄처럼 취급합니다.

에서 perldoc perlsyn, '선언'아래 :

Perl에서 선언해야 할 유일한 것은 보고서 형식과 서브 루틴 (때로는 서브 루틴조차도)입니다. 변수는 정의되지 않은 값 ( "undef")이 정의 된 값이 할당 될 때까지 "undef"가 아닌 다른 값을 보유합니다. 숫자로 사용될 때 "undef"는 0으로 취급됩니다. 문자열로 사용하면 빈 문자열로 취급됩니다. ""; 그리고 할당되지 않은 참조로 사용되면 오류로 취급됩니다.

다른 팁

Telemachus의 게시물에 대해 자세히 설명하기 위해, 비 초기 값은 정의되지 않습니다. 구조의 깊은 부분은 다음과 같습니다 자가 변형. 이것은 데이터 구조가 자동으로 만들어지는 편리한 기능입니다. 자가 변형은 원할 때 훌륭하지만 방지하고 싶을 때는 고통이 될 수 있습니다. 자동 변형 이해에 대한 인터넷 주변에는 많은 튜토리얼, 기사 및 게시물이 있습니다.

정의되지 않은 채로 $ref 그리고 $ref->{ipv6}{pa}{'foo'}++, $ref 값이 할당됩니다.

$ref = { 
     ipv6 => { 
          pa => { 
              foo => undef
          }
     }
};

undef가 0으로 numife으므로 0 ++를 얻습니다. 1의 최종 결과는 다음과 같습니다. ref->{ipv6}{pa}{'foo'} == 1.

경고가 활성화 된 경우 (그렇습니다 use warnings;, 당신은 그렇지 않습니까?)이 정의되지 않은 값에서 작동 할 때 "비 초기의 값"경고를 받게됩니다. 단위화 된 값을 증가시키는 것이 원하는 동작이라면, 원하는 경고 그룹을 코드의 제한된 부분에서 전환 할 수 있습니다.

use strict;
use warnings;
my $res;

// run query to fetch IPv6 resources
while( my $row = $org_ip6_res->fetchrow_arrayref )
{   no warnings 'uninitialized';
    if( $row->[4] =~ /PA/ ) {
        $res->{ipv6}{pa}{$row->[2]}++;
    } elsif( $row->[4] eq 'PI' ) {
        $res->{ipv6}{pi}{$row->[2]}++;
    }
}

경고 계층 구조를 찾을 수 있습니다 perllexwarn.

기본적으로 정의되지 않지만 증가 할 때 0 인 것처럼 취급됩니다.

Perl Parlance의 용어는 'AutoVivified'입니다.

아마도 당신이하고 싶은 것은 사용하는 것입니다 키워드가 있습니다:

$res->{ipv6}{pa}{$row->[2]}++ if exists($res->{ipv6}{pa}{$row->[2]});

초기화되지 않은 해시와 같은 것은 없습니다 열쇠. 비 초기화 될 수있는 것은 다음과 같습니다 특정 키를 위해. 해시 값은 단지 스칼라 값입니다. 변수와 같은 것은 아닙니다 $foo.

예제에는 상호 작용하는 몇 가지 다른 Perl 기능이 있습니다.

처음에 $res 정의되지 않았습니다 (즉, 가치가 있습니다 undef). 비 초기 값을 해시 참조로 사용하는 경우 ( $res->{ipv6}...) perl "autovivivivivivies"로서. 즉, Perl은 익명 해시를 생성하고 값을 대체합니다. undef 새로운 해시를 참조하여. 이 프로세스는 결과 값을 참조로 사용할 때마다 (조용히) 반복됩니다.

결국, 당신은 당신의 길을 자동으로 바꿉니다 $res->{ipv6}{pa}{$row->[2]}, 정의되지 않았습니다. 이것은 단지 스칼라 값이라는 것을 기억하십시오 $foo. 행동은 말과 동일합니다

my $foo;
$foo++;

Perl은 정의되지 않은 값을 사용할 때 특별한 일을합니다. 숫자로 사용하면 Perl이 0으로 변환합니다. 문자열로 사용하면 Perl이`(빈 문자열)으로 변환합니다. 대부분의 상황에서는 "비 초기 가치 사용 ..."경고가 활성화 된 경우 경고를 얻을 수 있습니다 (필요한 경우). 그만큼 자동 증가 운영자 (++그러나)는 특별한 경우입니다. 편의를 위해 값을 조용히 변환합니다 undef 에게 0 그것을 증가시키기 전에.

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