2011-10-25 11 views
14

मैं सिर्फ कुछ बहुत ही अजीब व्यवहार है कि मैं वास्तव में व्याख्या कर सकते हैं नहीं का सामना करना पड़ा है:पर्ल करना ... जबकि और पिछले आदेश

do { 
    my $qry = $self->getHTMLQuery(undef, $mech->content()); 
    next if (!defined($qry)); 

    push(
     @prods, 
     map { 'http://www.XXXXYYYX.com'.$_->attr('href') } 
      $qry->query('div.prodInfo div.prodInfoBox a.prodLink.GridItemLink') 
    ); 

    $qry->delete(); 
    $TEST++; 

    last if ($TEST >= 10); 

} while(eval { $mech->follow_link(class => 'jump next') }); 

print "WHILE ENDED\n"; 

कोड कभी नहीं प्रिंट के ऊपर "जबकि समाप्त" ऐसा प्रतीत होता है, भले ही जबकि लूप से बाहर जाने के लिए जब $TEST> = 10

लेकिन निम्नलिखित कोड प्रिंट "जबकि समाप्त" करता है:

do { 
    my $qry = $self->getHTMLQuery(undef, $mech->content()); 
    next if (!defined($qry)); 

    push(
     @prods, 
     map { 'http://www.XXXXYYYX.com'.$_->attr('href') } 
      $qry->query('div.prodInfo div.prodInfoBox a.prodLink.GridItemLink') 
    ); 

    $qry->delete(); 
    $TEST++; 

} while(eval { $mech->follow_link(class => 'jump next') } && $TEST <= 10); 

print "WHILE ENDED\n"; 

दोनों परीक्षणों में,का प्रारंभिक मूल्य0.

do...while में last के व्यवहार for और while {...} में व्यवस्था से अलग है है?

+0

मैं दूसरी बार आप कहते हैं कि "उपरोक्त कोड" मान, आप वास्तव में मतलब है "कोड * नीचे * " – TLP

उत्तर

23

एक do ब्लॉक के रूप में अब तक next, last के रूप में एक असली लूप के रूप में गिनती नहीं है, और redo चिंतित हैं। इसका उल्लेख perlsyn में किया गया है, जहां आपको last काम करने के लिए एक नंगे ब्लॉक के साथ इसके आसपास के बारे में बताया गया श्वार्न टिप मिलेगा। लेकिन यह next के साथ काम नहीं करेगा, क्योंकि एक नंगे ब्लॉक को केवल एक बार निष्पादित किया जाता है, इसलिए nextlast जैसे कार्य करता है। next काम करने के लिए, आपdo के अंदर नंगे ब्लॉक डाल सकते हैं, लेकिन lastnext जैसा कार्य करेगा।

आप next और last दोनों की जरूरत है एक do ... while के साथ काम करने, सबसे आसान तरीका है एक continue ब्लॉक में वास्तविक स्थिति के साथ एक अनंत लूप का प्रयोग है। इन 2 छोरों, सिवाय दूसरा कोई वास्तविक पाश है कि, बराबर हैं तो यह next & last साथ काम करता है:

do { ... } while condition; 
while (1) { ... } continue { last unless condition }; 
+0

संपूर्ण स्पष्टीकरण, धन्यवाद! – snoofkin

21
perldoc -f last से

:

"पिछले" एक ब्लॉक है कि इस तरह के एक मान देता है के रूप में "eval {}", "उप {}" से बाहर निकलने या

"{करना}" करने के लिए इस्तेमाल नहीं किया जा सकता
14

टीएलपी सही है। इस के लिए मानक काम (मैंने इसे स्वयं हिट किया है) एक नंगे ब्लॉक में डू/जबकि लपेटना है, जो काउंटर-इंट्यूटिवली, सम्मान लूप नियंत्रण करता है।

{ do { 
    last; 
} while 1; } 

बाहर ब्लॉक last पकड़ जाएगा। यदि आप next को संभालना चाहते हैं तो आपको ब्लॉक को अंदर रखना होगा।

do {{ 
    next; 
}} while 1; 

अंदर ब्लॉक next पकड़ जाएगा।

दुर्भाग्य से आप दोनों नहीं कर सकते हैं। एक पाशन संशोधक के साथ

+1

वह 'अंतिम' को ठीक करेगा, लेकिन यह 'अगली' को ठीक नहीं करेगा। एक नंगे ब्लॉक के साथ, वे दो बराबर हैं (क्योंकि नंगे ब्लॉक केवल एक बार निष्पादित होते हैं)। – cjm

+0

@cjm अच्छा पकड़ो। और मैंने पाया कि आप दोनों नहीं कर सकते हैं।:-( – Schwern

+0

ठीक है, आप _could_, लेकिन आपको बाहरी ब्लॉक पर एक लेबल डालना होगा और फिर 'अंतिम लेबल' का उपयोग करना होगा। और यह केवल बग मांग रहा है, क्योंकि यदि आप लेबल भूल जाते हैं और केवल 'अंतिम' टाइप करते हैं, यह इसके बजाय 'अगली' की तरह कार्य करेगा। – cjm

संबंधित मुद्दे