2008-10-30 8 views
41

मेरे पास निम्न पर्ल कोड है जो टर्मिनल चौड़ाई प्राप्त करने के लिए Term::ReadKey पर निर्भर करता है; मेरा नेटबीएसडी बिल्ड इस मॉड्यूल को याद कर रहा है, इसलिए मॉड्यूल गायब होने पर मैं टर्मिनल की चौड़ाई को 80 तक डिफ़ॉल्ट करना चाहता हूं।मैं यह कैसे जांच सकता हूं कि इसका उपयोग करने से पहले मेरे पास पर्ल मॉड्यूल है या नहीं?

मैं यह नहीं समझ सकता कि कैसे मॉड्यूल का सशर्त रूप से उपयोग किया जाए, समय से पहले यह जानना कि यह उपलब्ध है या नहीं। मेरा वर्तमान कार्यान्वयन सिर्फ एक संदेश के साथ निकलता है कि यह अनुपस्थित होने पर Term::ReadKey नहीं मिल सकता है।

#/usr/pkg/bin/perl -w 
# Try loading Term::ReadKey 
use Term::ReadKey; 
my ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize(); 
my @p=(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97); 
my $plen=$#p+1; 
printf("num |".("%".int(($wchar-5)/$plen)."d") x $plen."\n",@p); 

मैं NetBSD पर पर्ल 5.8.7 और 5.8.8 का उपयोग कर रहा Cygwin पर तुम मुझे और अधिक प्रभावी ढंग मेरी स्क्रिप्ट में इस लागू करने में सहायता कर सकते हैं?

+3

मेरी राय में, या तो शीर्षक गलत है, या सभी जवाब है (सिवाय शायद मॉड्यूल :: लोड :: सशर्त, अगर check_install() प्रयोग किया जाता है का उपयोग कर एक) गलत हैं ।शीर्षक यह पूछने के लिए पूछता है कि "अगर मेरे पास इसका उपयोग करने से पहले एक पर्ल मॉड्यूल * है"। सभी उत्तरों "eval * के साथ त्रुटियों का पता लगाने * की आवश्यकता के दौरान कुछ भिन्नता का उपयोग करते हैं *। –

उत्तर

79

यहाँ एक नंगे हड्डियों समाधान है कि एक और मॉड्यूल की आवश्यकता नहीं है है:

my $rc = eval 
{ 
    require Term::ReadKey; 
    Term::ReadKey->import(); 
    1; 
}; 

if($rc) 
{ 
    # Term::ReadKey loaded and imported successfully 
    ... 
} 

नोट नीचे सभी जवाब (मुझे आशा है कि वे इस एक नीचे कर रहे हैं :-) कि उपयोग eval { use SomeModule } क्योंकि use गलत हैं कथन का मूल्यांकन संकलन समय पर किया जाता है, भले ही वे कोड में दिखाई दें। तो यदि SomeModule उपलब्ध नहीं है, तो स्क्रिप्ट संकलन के तुरंत बाद मर जाएगी।

(एक use स्टेटमेंट का एक स्ट्रिंग eval भी काम करेंगे (eval 'use SomeModule';), लेकिन वहाँ क्रम जब require/import जोड़ी एक ही बात करता है पर कोई मतलब नहीं पार्स करने और नए कोड संकलन है, और करने के लिए संकलन समय पर वाक्य रचना-जाँच की है बूट।)

अंत में, ध्यान दें कि eval { ... } और [email protected] का मेरा उपयोग इस उदाहरण के उद्देश्य के लिए संक्षेप में है। वास्तविक कोड में, आपको Try::Tiny, या कम से कम be aware of the issues it addresses जैसे कुछ का उपयोग करना चाहिए।

+0

डी ओह, मुझे पहले उस बारे में सोचना चाहिए था। +1 – ephemient

+1

हां वास्तव में काम करता है, और eval ब्लॉक के बाद सेमी-कोलन बहुत महत्वपूर्ण है। – dlamblin

+8

जितना संभव हो सके $ @ पर भरोसा करने से बचें। F.ex., कुछ मॉड्यूल एक साइड इफेक्ट के रूप में $ @ सेट कर सकते हैं जबकि वास्तव में अपवाद फेंकने के बिना लोड किया जा रहा है। बेहतर विकल्प इस तथ्य पर भरोसा करना है कि अपवाद पकड़े जाने पर 'eval' अपरिचित हो जाएगा, यानी। 'अगर (eval" टर्म :: ReadKey का उपयोग करें ") {...}'। –

10

सीपीएएन मॉड्यूल Module::Load::Conditional देखें। यह वही करेगा जो आप चाहते हैं।

+5

बेशक, यह केवल तभी काम करता है जब आपके पास इंस्टॉल किया गया हो। यदि आप करते हैं तो शायद एक बेहतर समाधान। – tvanfosson

+0

हाँ ... मैं गारंटी नहीं दे सकता कि मेरे पास वह है। और पता लगाएँ :: मॉड्यूल है, यह इसके $ install-> मॉड्यूल() मॉड्यूल नामों की सूची लौटाए गए सभी मॉड्यूल सूचीबद्ध नहीं करता है। – dlamblin

6

क्लासिक उत्तर (कम से कम, 'उपयोग' होने से पहले पर्ल 4 पर वापस डेटिंग) एक मॉड्यूल की आवश्यकता है()। संकलित होने के बजाए इसे स्क्रिप्ट चलाया जाता है, और आप सफलता या विफलता के लिए परीक्षण कर सकते हैं और उचित प्रतिक्रिया दे सकते हैं।

4

और आप मॉड्यूल के विशेष संस्करण की आवश्यकता होती है:

my $GOT_READKEY; 
BEGIN { 
    eval { 
     require Term::ReadKey; 
     Term::ReadKey->import(); 
     $GOT_READKEY = 1 if $Term::ReadKey::VERSION >= 2.30; 
    }; 
} 


# elsewhere in the code 
if ($GOT_READKEY) { 
    # ... 
} 
4
if (eval {require Term::ReadKey;1;} ne 1) { 
# if module can't load 
} else { 
Term::ReadKey->import(); 
} 

या

if (eval {require Term::ReadKey;1;}) { 
#module loaded 
Term::ReadKey->import(); 
} 

नोट: 1; केवल कार्यान्वित करता है, तो require Term::... ठीक से भरी हुई।

0

मुझे लगता है कि यह चर का उपयोग करते समय काम नहीं करता है। की जांच करें this link जो बताते हैं कि यह कैसे चर

$class = 'Foo::Bar'; 
     require $class;  # $class is not a bareword 
    #or 
     require "Foo::Bar"; # not a bareword because of the "" 

साथ इस्तेमाल किया जा सकता समारोह की आवश्यकता होती है @INC सरणी में "फू :: बार" फ़ाइल के लिए दिखेगा और नहीं मिल "फू के बारे में शिकायत करेंगे :: बार " क्या आप वहां मौजूद हैं। इस मामले में आप कर सकते हैं:

eval "require $class"; 
संबंधित मुद्दे

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