2010-02-14 21 views
10

Mastering Perl में अध्यायों में से एक में, ब्रायन डी फोय इस स्निपेट को List::Util से दिखाता है:इस पर्ल सबराउटिन में 'उपयोग वर्स' का क्या मतलब है?

sub reduce(&@) { 
    my $code = shift; 
    no strict "refs"; 
    return shift unless @_ > 1; 
    use vars qw($a $b); 
    my $caller = caller; 
    local(*{$caller . "::a"}) = \my $a; 
    local(*{$caller . "::b"}) = \my $b; 
    $a = shift; 
    foreach(@_) { 
     $b = $_; 
     $a = &{$code}(); 
    } 
    $a; 
} 

मुझे समझ में नहीं आता use vars qw($a $b) लाइन का बिंदु क्या है। यहां तक ​​कि अगर मैं इसे टिप्पणी करता हूं, तो मुझे एक ही आउटपुट & चेतावनियां मिलती हैं।

+1

क्या आपने 'सख्त उपयोग' का उपयोग किया था; चेतावनियों का प्रयोग करें; 'इससे ​​पहले? – Ether

+4

एक क्विबल - सूचीबद्ध कोड ब्रायन डी फोय नहीं है - वह ग्राहम बार (सूची :: यूटिल के निर्माता) – DVK

+0

से कोड उद्धृत कर रहा है हां मैंने किया। क्यूं कर? – Geo

उत्तर

11

ऐसा इसलिए किया जाता है क्योंकि सूची :: उपयोग आंतरिक रूप से कम() फ़ंक्शन का उपयोग करता है।

use strict; 
use warnings; 

package List::MyUtil; 

sub reduce (&@) { 
    # INSERT THE TEXT FROM SUBROUTINE HERE - deleted to save space in the answer 
} 

sub x { 
    return reduce(sub {$a+$b}, 1,2,3); 
} 

package main; 
my $res = List::MyUtil::x(); 
print "$res\n"; 

और फिर चल: निम्नलिखित कोड चलाकर

Name "List::MyUtil::a" used only once: possible typo at a.pl line 35. 
Name "List::MyUtil::b" used only once: possible typo at a.pl line 35. 

आप खुद के लिए यह देख सकते हैं:

use vars की abscence में, निम्न चेतावनी जब समारोह प्रयोग किया जाता है दिया जाता है यह फिर से use vars अक्षम के साथ।

+0

तथ्य यह है कि पैकेज कम उपयोग करता है अब समझ में आता है। उस स्पष्टीकरण के बिना, मुझे नहीं पता था कि क्या विश्वास करना है। – Geo

+0

एक और सवाल, अगर मैं कर सकता हूं। व्याख्यात्मक $ ए और $ बी का क्या मतलब है? उन्होंने वैश्विक लोगों का संदर्भ क्यों नहीं दिया? – Geo

+3

सही उत्तर के लिए टिप-ऑफ इस तथ्य में निहित है कि वर्र्स का उपयोग केवल वर्तमान पैकेज पर लागू होता है। इस प्रकार यह सूची :: किसी भी व्यक्ति द्वारा स्वयं के लिए कोई उपयोग नहीं होगा। – DVK

2

DVK नोट्स के रूप में, यदि हम use vars के साथ कोड चलाते हैं, तो हमें केवल एक बार उपयोग किए जा रहे चर के बारे में चेतावनी मिलेगी।

चेतावनी को दबाने का एक और तरीका कॉलर पक्ष पर है - यानी reduce फ़ंक्शन के बजाय reduce पर कॉल करें। List::Util या List::MoreUtils से फ़ंक्शंस का उपयोग करते समय इसे संदर्भित करना होगा जो कोड संदर्भ लेते हैं (उदाहरण के लिए, pairwise)। इन दोनों दृष्टिकोण कॉलर पक्ष पर काम करते हैं:

my @sums = pairwise { no warnings 'once'; $a + $b } @x, @y; 

my @sums = pairwise { our($a, $b);  $a + $b } @x, @y; 
+0

सही - लेकिन अगर कम() वास्तव में सूची :: उपयोग में कई बार उपयोग किया जाता है, तो इसे कम करने के बाद केवल एक बार मॉड्यूल लेखक के लिए बेहतर दृष्टिकोण है, हालांकि यह पाठ्यक्रम के मॉड्यूल का उपयोग करने में लोगों की मदद नहीं करता है:) – DVK

0

उस कोड के बाद अनुच्छेद से ठीक है। पैकेज और लेक्सिकल वैरिएबल का एक ही स्कोप में मिश्रण है:

शेष तत्वों को पैकेज तत्वों में $ 1 और $ b में दो तत्व डालकर सॉर्ट की तरह काम करता है। ग्राहम उन नामों के साथ शब्दावली चर को परिभाषित करता है, और प्रतीकात्मक संदर्भों का उपयोग कर कॉलिंग पैकेज में तुरंत $ और $ b के लिए टाइपग्लोब को असाइन करता है। इसके बाद $ ए और $ बी के मूल्य लेक्सिकल संस्करण हैं। जब वह subroutine तर्क & {$ कोड}() को कॉल करता है, तो वह कोड उसके पैकेज चर को देखता है, जो प्रभावशाली होते हैं जब मैंने subroutine लिखा था। समझ गया? अंदर के अंदर, मैं व्याख्यात्मक संस्करणों का उपयोग कर रहा हूं, लेकिन $ कोड के अंदर, मैं कॉलिंग पैकेज से पैकेज संस्करणों का उपयोग कर रहा हूं। यही कारण है कि ग्राहम ने उन्हें एक-दूसरे के उपनाम बनाये।

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