2010-10-10 13 views
6

मैं इस इंटरफेस वाले पुनरावर्तक है:एक इटरेटर को सूची में विस्तारित करने के लिए पर्ल में सबसे शानदार तरीका क्या है?

वर्तमान कार्यान्वयन next_hsp $ hit-> listify के लिए यह है:

my @list; 
while (my $hsp = $hit->next_hsp) { 
    push(@list, $hsp); 
} 

अब मैं सोच रहा हूँ कि वहाँ भी कम समय में यह करने के लिए बेहतर तरीके हो सकते हैं कोड। आप क्या कहते हैं, स्टैकर?

+0

हमें पूर्ण प्रदर्शन कार्यक्रम दिखाएं, ताकि हम चीजें देख सकें जैसे कि आपको '$ हिट' कैसे मिला। –

उत्तर

3

यह पूरी तरह से पुनरावर्तक कार्यान्वयन पर निर्भर करता है। यदि next_hsp एकमात्र उपलब्ध विधि है, तो आप इसे सही कर रहे हैं।

5

सभी संकेतक मैंने कभी भी undef को वापस संकेत दिया है कि वे थक गए हैं। इसलिए आपको while (defined(my $hsp = $hit->next_hsp)) लिखना चाहिए। निम्नलिखित उदाहरण प्रश्न में गलती का प्रदर्शन करता है जो परिभाषा के बजाय सत्य (परीक्षण 1) पर परीक्षण करता है (पास 'लिफ्टऑफ')।

use 5.010; 
my $hit = __PACKAGE__; 

sub next_hsp { 
    state $i; 
    $i++; 
    return ['mumble', 4, 3, 2, 1, 0, 'liftoff']->[$i]; 
} 

# insert snippet from question here 
+0

यह एक अच्छा मुद्दा है। यह पूरी चीज को और भी कमजोर बनाता है, लेकिन आप सही हैं। – Mithaldu

+2

एक सामान्य पैटर्न एक इटरेटर के लिए अंत में कोई तर्क के साथ बस 'वापसी' करने के लिए है। एक स्केलर संदर्भ में जो 'undef' में बदल जाता है लेकिन यदि आप' मेरा ($ hsp) = $ hit-> next_hsp' कहते हैं तो इटेटरेटर मामलों में सुरक्षित रूप से अनावश्यक (या कुछ और जिसे गलत के रूप में व्याख्या किया जा सकता है) का मूल्य वापस कर सकता है जहां ऐसा करना समझ में आता है। यह काम करता है क्योंकि 1 मान वाले एक सूची में बुलियन सत्य होगा चाहे यह मान गलत है या यहां तक ​​कि अनिश्चित है। –

+2

सभी इटरेटर? मैंने काफी संख्या देखी है जो अनंत हैं। :) –

3

गोल्फ खेल के बारे में चिंता मत करो, कोड आपके पास ठीक (defined उपयोग के बारे में अन्य उत्तर के अलावा अन्य) लग रहा है। हालांकि, अगर आप खुद को इस पैटर्न को दोहराते हैं तो 2 चीजें दिमाग में आती हैं।

पहले स्पष्ट है, यह एक उपयोगिता समारोह में refactor, ताकि आप my @list = expand($hit).

है दूसरा सवाल थोड़ा गहरा है - लेकिन मेरे लिए गोल्फ खेल की तुलना में अधिक बदबू आ रही है। इटेटरेटर्स का पूरा बिंदु उपभोग करना है क्योंकि आपको उनकी आवश्यकता है, इसलिए यदि आप इसे अक्सर ऐसा करते हैं, तो क्या आप वाकई सही काम करना चाहते हैं? शायद आप इस डेटा को अपने स्वयं के एपीआई के बाहर ले जा रहे हैं, इसलिए आप किसी अन्य विकल्प के लिए बाध्य हैं, लेकिन यदि आपके पास सूची के बजाय एक इटरेटर का उपभोग करने का विकल्प है, तो शायद यह एक क्लीनर समाधान होगा।

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