2008-10-21 7 views
10

분명히 필요하지 않습니다. 나는 여기서 무슨 일이 일어나고 있는지 궁금해. 내가 누락 된 뭔가 간단? 펄의 모든 버전에서이 동작에 의존 수)

펄 v5.8.8 :

%h = (0=>'zero', 1=>'one', 2=>'two'); 
while ($k = each %h) { 
    $v = delete $h{$k}; 
    print "deleted $v; remaining: @h{0..2}\n"; 
} 

출력

deleted one; remaining: zero two 
deleted zero; remaining: two 
deleted two; remaining: 

man perlfunc (각)을 루프가 계속하면서 그 이유를 설명하지 않습니다 $k에 0이 할당 된 경우 코드는 while 루프 의 조건이 ($k = each %h, defined $k) 인 것처럼 동작합니다. 예상대로 루프 조건이 실제로 ($k = each %h, $k)로 변경되면

다음은 $k = 0에서 실제로 정지한다.

는 또한 each의 다음 다시 구현을 위해 $k = 0에서 정지 :

%h = (0=>'zero', 1=>'one', 2=>'two'); 
sub each2 { 
    return each %{$_[0]}; 
} 
while ($k = each2 \%h) { 
    $v = delete $h{$k}; 
    print "deleted $v; remaining: @h{0..2}\n"; 
} 

출력 단지 : 당신은 스칼라 문맥에서 each를 호출하고

deleted one; remaining: zero two 

답변

29

,이 때문에의 작동하지 않도록 목록 반환 값.

그냥 그렇게 op.c에서 일어나는 5.8.8에서

while ($key = each %hash) 

, 선 3760-3766이며,

while ($line = <FILE>) 

이 암시 defined를 추가하는 특수 맡았다처럼 :

case OP_SASSIGN: 
    if (k1->op_type == OP_READDIR 
     || k1->op_type == OP_GLOB 
     || (k1->op_type == OP_NULL && k1->op_targ == OP_GLOB) 
     || k1->op_type == OP_EACH) 
    expr = newUNOP(OP_DEFINED, 0, expr); 
    break; 

모든 펄 버전에 적용되는지 확실하지 않습니다.

다음을 참조하십시오. PerlMonks의 When does while() test for defined vs truth. Perl 문서에서이 부분이 언급 된 곳을 찾을 수 없습니다 (<FILE> 사례가 언급되었지만 each 사례가 표시되지 않음).

0

감사합니다. cjm. defined 의 암시 적 추가의 어떤 종류가 glob에 대해서는 그런 것처럼 진행되었지만, 그것이 어디에 있는지는 분명하지 않습니다. 이 문서화되어 있습니다. 지금 나는 특별한 취급이 적용되는 의 제한된 경우를 안다.

하지만 정보는 Perl 소스 코드가 아닌 perlfunc 문서에 나와 있습니다. !

6

cjm이 맞습니다. 이 질문에 이상한 점을 지적 할 때 펄 코드가 B::Deparse으로 실행되어 펄의 코드를 이해하는 데 도움이된다. 나는 우선 순위 실수를 보여주기 위해 -p 스위치를 사용하기를 좋아한다.

$ perl -MO=Deparse,p your_example.plx 
(%h) = (0, 'zero', 1, 'one', 2, 'two'); 
while (defined($k = each %h)) { 
    $v = delete $h{$k}; 
    print "deleted $v; remaining: @h{0..2}\n"; 
} 
your_example.plx syntax OK