2010-06-14 19 views
6

कभी-कभी मुझे एक उपयोगी प्रोग्रामिंग फ़ंक्शन की आवश्यकता होती है, जैसे List::Util::max एक बड़े प्रोग्राम के बीच में जो बहुत सारी चीज़ें करता है। तो अगर मैंबड़े पैमाने पर उपयोगी कार्यों को बड़े पैमाने पर आयात करना

use List::Util 'max'; 

करना मेरा कार्यक्रम के शीर्ष पर, मुझे लगता है कि प्रतीक के साथ अटक कर रहा हूँ, मेरी पूरी नेमस्पेस को दूषित है, भले ही मैं केवल एक सबरूटीन में इसकी आवश्यकता है।

तो मैं एक अलग तरीके की कोशिश कर के बारे में सोच किया गया है, बजाय:

use List::Util(); 

# a whole bunch of stuff later... 
sub blah { 
    List::Util->import('max'); 
    $blah = max @foobar; 
    ... 
} 

इस के साथ दो समस्याओं, हालांकि कर रहे हैं। एक के लिए, यह ब्लॉक (ड्रैट।) के अंत में स्वचालित रूप से अनमोर्ट नहीं होता है, मुझे unimport के साथ सबकुछ पूर्ववत करना होगा।

दूसरी समस्या यह है कि स्पष्ट रूप से प्रोटोटाइप सही ढंग से लागू नहीं होते हैं, इसलिए मुझे सुंदर पेरेंटलेसलेस संस्करण के बजाय max(@foobar) कहना है।

क्या एक ब्लॉक के लिए अस्थायी रूप से प्रतीकों को आयात करने का कोई आसान तरीका है, जो स्वचालित रूप से ब्लॉक के अंत में उन्हें दूर कर देगा, और भी प्रोटोटाइप को सही ढंग से संभाल लेंगे?

उत्तर

1

आप एक प्रतीक तालिका प्रविष्टि स्थानीयकरण कर सकते हैं:

use List::Util(); 

@y = qw(1 3 5 -9 4); 

sub max { # return maximum *absolute value* of list 
    my $max = abs(shift); 
    $max<abs($_) && ($max=$abs($_)) for @_; 
    return $max; 
} 

sub max2 { 
    local *max = *List::Util::max; 
    return max(@_); 
} 

print "My max:   ", max(@y), "\n"; # ==> 9 
print "List::Util::max ", max2(@y), "\n"; # ==> 5 
+3

यह सूक्ष्म त्रुटियों को पेश करेगा यदि 'अधिकतम' का प्रोटोटाइप है, क्योंकि इसका प्रभाव संकलन समय पर जला दिया जाता है। 'Max2' में,' मुख्य :: अधिकतम' से प्रोटोटाइप का उपयोग किया जाता है, न कि 'सूची :: Util :: max' से। मददगार रूप से, आपको असाइनमेंट पर प्रोटोटाइप विसंगति के बारे में चेतावनी मिलनी चाहिए। –

+0

@ एरिक स्ट्रॉम - अच्छा बिंदु, वह चूसना होगा। सावधानी के साथ 'स्थानीय' सबराउटिन नाम का प्रयोग करें। – mob

4

बस ऐसा करते हैं, यह ज्यादा बेहतर और क्लीनर है:

package Foo; 
use strict; use warnings; 
use List::Util 'max'; 
use namespace::autoclean; 

# your method definitions here... 

namespace::autoclean "unimport" पैकेज का संकलन चक्र के बाद प्रतीक किया जाता है जाएगा। आपकी विधि में इसे कॉल करने के लिए अभी भी कॉल किया जाएगा, लेकिन आपके पास कोई नेमस्पेस प्रदूषण नहीं है (*Foo::max प्रतीक हटा दिया गया है) और $obj->max() को कॉल करना विफल हो जाएगा।

वैकल्पिक रूप से, आप Lexical::Import पर एक नज़र डालना चाहते हैं (मुझे इसके बारे में कुछ भी पता नहीं है; एक आईआरसी बर्डी ने इसका उल्लेख किया है)।

+0

है जो मैं वास्तव में हासिल करने की कोशिश कर रहा हूं। मैं चाहता हूं कि मेरे उपयोगिता कार्यों को शब्दावली चर के समान व्यवहार करना पड़े। – friedo

+0

@friedo: यह एक समस्या क्यों है कि पूरे पैकेज में 'अधिकतम' उपलब्ध है? यदि चिंता नामस्थान प्रदूषण है, तो यही मॉड्यूल का ख्याल रखता है। – Ether

+0

शायद मैं पैकेज में कहीं और * अलग * 'अधिकतम 'चाहता हूं। – friedo

1

perlfunc का तात्पर्य है कि no MODULE आप क्या चाहते हैं करना चाहिए:

sub blah { 
    use List::Util qw(max); 
    say max @foobar; 
    no List::Util; 
} 

लेकिन वह काम नहीं करता - कम से कम सूची के लिए नहीं: : util। मेरा मानना ​​है कि इसे unimport विधि को परिभाषित करने की आवश्यकता होगी। फिर भी, मुझे यकीन नहीं है कि क्या आपके मॉड्यूल कॉल में अलग-अलग परिभाषाओं में max हो सकता है।

+0

उप-परिभाषा के बाकी हिस्सों की तुलना में 'उपयोग' और 'नहीं' रेखाएं एक अलग (पहले) समय पर निष्पादित नहीं होंगी? – Ether

+0

दोनों 'उपयोग' और 'नहीं' संकलन समय पर होते हैं; उन्हें 'ब्लहा' संकलित किया गया था, जबकि उन्हें निष्पादित किया जाएगा। –

2

यदि आप केवल एक सबराउटिन में अधिकतम उपयोग करते हैं, तो मैं इसे नामस्थान में आयात नहीं करता। नाम स्थान :: autoclean` spiffy है, यह मुख्य समस्या है कि `max` अभी भी वहाँ पूरे पैकेज में सीमित के बजाय एक ही ब्लॉक, करने के लिए है का समाधान नहीं करता है` मेरे समाधान

use List::Util; 
sub blah { 
    print List::Util::max(@list); 
} 
+0

यह अभी भी प्रोटोटाइप का सम्मान करता है, इसलिए आप ब्रैकेट छोड़ सकते हैं: प्रिंट सूची :: Util :: max @list; – dwarring

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