2012-10-23 8 views
6

को समझना मैं कुछ वर्षों के दौरान apache mod_cgi का उपयोग कर रहा हूं। अब मैं mod_perl पर जा रहा हूं और मुझे कुछ समस्याएं मिली हैं, विशेष रूप से subroutines के साथ। अब तक मैं my, our और न ही local का उपयोग कभी नहीं कर रहा था; और सीजीआई स्क्रिप्ट समस्याओं के बिना काम किया। प्रलेखन पढ़ने के बाद और यहां पोस्ट किए गए कुछ पिछले प्रश्नों को मैं my, our और local काम करता है या नहीं। मेरी चिंता यह है कि अगले अनुरोधों के बीच कौन सी सूचना साझा की जा रही है (यदि मैं सही ढंग से समझता हूं, तो यह मुख्य चिंता है जो mod_cgi के बजाय mod_perl चलाने के दौरान होनी चाहिए)।सीजीआई से mod_perl में स्थानांतरित करना। मेरे, हमारे, स्थानीय

  • क्या my के रूप में विशेष तरह के घोषित करने के बिना एक अदिश या सिर्फ अदिश में our का उपयोग कर के बीच कोई अंतर है? वैश्विक दोनों नहीं हैं?
  • यदि मैं स्केलर को निजी के रूप में घोषित नहीं करता हूं तो अगले अनुरोध में साझा किया जा रहा है? एक ही सर्वर में एक अलग पर्ल स्क्रिप्ट के एक और अनुरोध में भी?
  • मैं subroutine के बाहर एक subroutine के अंदर एक स्केलर के मूल्य को कैसे साझा कर सकता हूं लेकिन उसी फ़ाइल के बाहर नहीं और न ही एक ही अनुरोध?
  • यदि मैं फ़ाइल के समान स्तर में या उसी सबराउटिन में if के अंदर एक स्केलर में my का उपयोग करता हूं, और उसके बाद मैं एक और if बनाता हूं जहां मैं एक ही स्केलर का उपयोग करता हूं; क्या यह स्केलर if और प्रत्येक if दोनों के बीच साझा किया गया है अलग-अलग ब्लॉक? while और for के बारे में क्या, क्या वे पहले से घोषित my स्केलर के रूप में अलग-अलग ब्लॉक हैं या केवल subroutines और फ़ाइलों के लिए काम करता है?
+4

जब तक आप विशेष रूप से, अपाचे की हिम्मत के साथ इंटरफेस करने की जरूरत है आप सिर्फ बातें तेजी लाने के लिए, मोड-पर्ल लंघन और [Plack] (https करने के लिए सीधे आगे बढ़ने पर विचार करना चाहते हैं: // metacpan.org/module/Plack) और फास्टसीजीआई। mod_perl आपको अपाचे से जोड़ता है, पूरी HTTP प्रक्रिया को फहराता है और स्मृति को रिसाव कर सकता है। कई पर्ल वेब ढांचे बेकार के साथ काम करते हैं। हालांकि, वैश्विक बनाम अक्षीय चर के साथ इसी तरह के मुद्दे हैं, इसलिए आपका प्रश्न प्रासंगिक बना हुआ है। – Schwern

+0

@ ज़िलो: आप बहुत चुप हो गए हैं। क्या इनमें से कोई भी जवाब आपको बताता है कि आपको क्या जानने की आवश्यकता है? – Borodin

+0

@Schwern मैंने लाइटसीपीआई पर फास्टसीजीआई चलाने की कोशिश की है लेकिन सेटअप करना आसान नहीं था।मैं Lighttpd पर PHP के लिए फास्टसीजीआई का उपयोग कर रहा हूं लेकिन पर्ल स्क्रिप्ट को संभालने के लिए फास्टसीजीआई स्थापित करने के लिए और अधिक जटिल लगता है। – Zillo

उत्तर

8

संपादित करें: यह केवल पर्ल वैरिएबल स्कॉइंग पर सामान्य जानकारी है। विशिष्ट mod_perl समस्याओं के लिए कृपया बोरोडिन की पोस्ट देखें।

my के साथ घोषित चर वैक्सिकल हैं। दूसरे शब्दों में, वे केवल वर्तमान दायरे में मौजूद हैं। आपको डिफ़ॉल्ट रूप से my के साथ अपने सभी चर घोषित करना चाहिए; जब आप विशेष रूप से विभिन्न कार्यक्षमता चाहते हैं तो केवल कुछ और करें।

लेक्सिकली-स्कोप्ड चर का उपयोग करना (लगभग) किसी भी भाषा में अच्छे कोड डिज़ाइन का मूल हिस्सा है। आपकी सभी स्क्रिप्ट में use strict; और use warnings; डालकर आपको इस अच्छे अभ्यास का पालन करने की आवश्यकता होगी।

our वैश्विक चर घोषित करने का एक तरीका है; अंतर्निहित परिणाम अविकसित ग्लोबल्स का उपयोग करने के समान ही है। हालांकि, इसमें दो मतभेद हैं:

  1. आप स्पष्ट रूप से बता रहे हैं कि आप चर वैरिएबल होना चाहते हैं। यह पालन करने के लिए एक अच्छा अभ्यास है, क्योंकि वैश्विक चर का उपयोग असाधारण मामला होना चाहिए। इस वजह से, आप इस तरह से वैश्विक बना सकते हैं भले ही आप use strict;
  2. our के साथ घोषित वैरिएबल वर्तमान नाम में सभी संकुलों के दौरान घोषित किए गए नाम से पहुंच योग्य होगा। इसके विपरीत, एक अविकसित चर, वर्तमान पैकेज के भीतर सरल नाम से ही पहुंच योग्य है। इसके बाहर, आप इसे केवल $package::variable के रूप में देख सकते हैं।

अधिक जानकारी के लिए the documentation for our देखें।

local एक व्याख्यात्मक चर नहीं बनाता है; इसके बजाए, यह वैश्विक चर को वर्तमान दायरे में एक अस्थायी मूल्य देने का एक तरीका है। यह ज्यादातर पर्ल के विशेष में निर्मित (विराम चिह्न) चर के साथ प्रयोग किया जाता है:

{ 
    local $/; #make the record separator undefined in this scope only. 
    my $file = <FILE>; #read in an entire file at once. 
} 

आप अपने चर के लिए हर समय my का उपयोग कर और केवल ऊपर दिखाए गए ऐसे ही विशेष मामलों के लिए local का उपयोग करके अब तक बस जा सकते हैं।

+1

यह * mod \ _perl * – Borodin

+0

@ बोरोडिन द्वारा लगाए गए बहुत ही अलग वातावरण का कोई खाता नहीं लेता है, ओह, यह एक निरीक्षण था। मैंने प्रश्न को पढ़ा नहीं है कि समझने के लिए कि पर्ल में बुनियादी स्कोपिंग कैसे काम करती है, और 'mod_perl' भाग के बारे में भूल गई। – dan1111

+0

फिर भी सामान्य पर्ल चर श्रेणियों का एक उपयोगी स्पष्टीकरण – Borodin

17

mod_perl स्क्रिप्ट के नाम और पथ के आधार पर पैकेज के भीतर handler नामक एक उपराउटिन में प्रत्येक पर्ल स्क्रिप्ट को लपेटकर काम करता है। प्रत्येक स्क्रिप्ट को चलाने के लिए एक नई प्रक्रिया शुरू करने के बजाय, यह handler सबराउटिन को लगातार पर्ल थैड्स में से एक द्वारा बुलाया जाता है।

आमतौर पर इस ज्ञान mod_cgi से पर्यावरण में परिवर्तन को समझने के लिए बहुत मदद मिलेगी, लेकिन जब से तुम कभी नहीं किया है, आपकी कार्यक्रमों के लिए use strict और घोषित चर के कामकाज से परिचित आपको बस इतना करना लोकप्रिय हो रहा का एक बहुत है बन !

मोड-पर्ल पर्यावरण गैर स्पष्ट सुरक्षा उल्लंघनों के कारण के लिए क्षमता है, और आप हर स्क्रिप्ट पर use strict के लिए अब शुरू करते हैं और घोषित हर चर चाहिए। use Carp आपको त्रुटि लॉग को समझने में भी मदद करेगा।

our के साथ घोषित एक वैरिएबल नाम एक ही नाम के पैकेज वैरिएबल के लिए एक व्याख्यात्मक-स्कोप्ड समानार्थी है जिसका उपयोग पैकेज नाम सहित नाम को पूरी तरह अर्हता प्राप्त किए बिना किया जा सकता है। उदाहरण के लिए, आमतौर पर our $var के साथ घोषित एक चर $main::var स्केलर तक पहुंच प्रदान करेगा (यदि घोषणा नहीं है) main:: निर्दिष्ट किए बिना। हालांकि, ऐसे चर जो undef के mod_cgi में mod_perl थ्रेड के पिछले निष्पादन से अपने मान बनाए रखेंगे, और निरंतरता के लिए हमेशा घोषणा के बिंदु पर उन्हें प्रारंभ करना सुरक्षित है। ध्यान दें कि mod_perl रैपिंग के कारण डिफ़ॉल्ट पैकेज नाम अब main नहीं है, इसलिए आप main:: उपसर्ग का उपयोग करके पैकेज चर का उपयोग नहीं कर सकते हैं, और पैकेज के वास्तविक नाम को खोजने के लिए मूर्खतापूर्ण है और स्पष्ट रूप से इसका उपयोग करें क्योंकि यह बहुत लंबा नाम होगा और यदि आप अपनी स्क्रिप्ट को स्थानांतरित या नाम बदलते हैं तो बदल जाएगा।

my वैरिएबल वह है जो पैकेज प्रतीक तालिका से स्वतंत्र रूप से मौजूद है, और आम तौर पर इसका जीवनकाल संलग्न फ़ाइल (फाइल स्कोप पर घोषित चर के लिए) या सबराउटिन का रन टाइम होता है। वे mod_perl में सुरक्षित हैं यदि दोनों स्क्रिप्ट के फ़ाइल दायरे में या पूरी तरह से एक सबराउटिन के भीतर पूरी तरह से उपयोग किए जाते हैं और उपयोग करते हैं, लेकिन यदि आप स्कॉप्स को मिश्रित करते हैं और फ़ाइल स्कोप पर my $global घोषित करते हैं और फिर इसे सबराउटिन में उपयोग करने का प्रयास करते हैं तो आप स्टंग हो सकते हैं। इसका कारण सरल नहीं है, लेकिन mod_perlhandler सबराउटिन में आपकी स्क्रिप्ट को लपेटने के कारण होता है, इसलिए आपके पास सबराउटिन घोषणाएं घोंसला होती हैं। आंतरिक subroutine केवल $global के पहले तात्कालिकता को अपनाने और बाद में कॉल द्वारा बनाए गए किसी भी अन्य को handler पर अनदेखा कर देगा। यदि आपको वैश्विक चर की आवश्यकता है तो आपको इसे our के साथ घोषित करना चाहिए और ऊपर वर्णित अनुसार घोषणा में इसे आरंभ करना चाहिए।

local वैरिएबल our वैरिएबल जैसा है कि यह एक पैकेज चर के पर्याय का पर्याय बनता है। हालांकि यह अस्थायी रूप से उस चर के वर्तमान मूल्य को बचाता है और फ़ाइल या ब्लॉक स्कोप के अंत तक उपयोग के लिए एक नई प्रति प्रदान करता है। अपने स्वचालित निर्माण और इसके दायरे में हटाने के कारण mod_perl स्क्रिप्ट्स में विशेष रूप से जहां आप डेटा संरचनाओं के पॉइंटर्स का उपयोग कर रहे हैं, कहें, CGI कक्षा का उदाहरण उदाहरण के लिए यह उपयोगी विकल्प हो सकता है। our $cgi = CGI->new घोषित करना सही ढंग से ऑब्जेक्ट बना देगा, लेकिन mod_perl के दृढ़ता के कारण, इसे स्मृति में तब तक छोड़ देगा जब तक कि थ्रेड के अगले निष्पादन को किसी अन्य के लिए जगह बनाने के लिए हटा दिया न जाए।

अपने प्रश्नों के लिए के रूप में:

  • एक चर का उपयोग करना यह या तो घोषित करने के बिना एक संकलन समय त्रुटि होती है यदि use strict जगह के रूप में यह होना चाहिए है। अन्यथा यह वर्तमान पैकेज नामस्थान में उस चर के लिए समानार्थी है।

  • चर या तो पैकेज चर या लेक्सिकल चर हैं; निजी जैसे चर को घोषित करने का कोई तरीका नहीं है। लेक्सिकल वैरिएबल (my के साथ घोषित) को स्क्रिप्ट के प्रत्येक निष्पादन के साथ बनाया और नष्ट कर दिया जाएगा, जब तक कि आपने एक अमान्य क्लोजर को उपरोक्त वर्णित एक सबराउटिन लिखकर ऊपर वर्णित किया है, जो एक विस्तृत दायरे में घोषित चर का उपयोग करता है, जब चर होगा लगातार लेकिन वह नहीं करेगा जो आप चाहते हैं। our के साथ घोषित एक वैरिएबल स्क्रिप्ट को कॉल में अपना मान बरकरार रखेगा, जबकि स्क्रिप्ट समाप्त होने पर local के साथ घोषित किया जाएगा। our और local चर दोनों पैकेज चर हैं और समान चर नाम के सभी संदर्भ समान चर को संदर्भित करते हैं।

  • एक वेरिएबल घोषित करने के लिए जो किसी भी स्क्रिप्ट के किसी भी कॉल के भीतर लगातार पहुंच योग्य है, आप या तो local चर या प्रारंभिक our चर का उपयोग कर सकते हैं। फ़ाइल स्कोप local $global पर mod_perl स्क्रिप्ट के लिए our $global = undef के बराबर है। यदि आप डेटा संरचना को इंगित करने के लिए our चर का उपयोग करते हैं तो undef $global के साथ स्क्रिप्ट के अंत में इसे नष्ट करना याद रखें।

  • my चर के लिए अद्वितीय है, और भीतर, ब्लॉक, जिसमें वे घोषित किया गया है दिखाई दे रहे हैं, कि एक if, while या for, या यहाँ तक कि सिर्फ एक नंगे { ... } ब्लॉक दायरे के भीतर एक ब्लॉक है या नहीं। अस्थायी कार्य चर के लिए हमेशा my चर का उपयोग करें जो केवल एक ब्लॉक के भीतर उपयोग किए जाते हैं और कहीं और से नहीं पहुंचते हैं।

मुझे आशा है कि इस मदद करता है

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