2010-05-27 18 views
7

मैं सोच रहा था कि पर्ल में सबसे अच्छा अभ्यास क्या हो रहा है - या, अधिक महत्वपूर्ण बात यह है कि मॉड्यूल को $Module::varName तक सीधे पहुंचकर कुछ मॉड्यूल का वैश्विक चर है, यदि मॉड्यूल इसके लिए गेटर/सेटर विधि प्रदान नहीं करता है।क्या यह उचित है और विशेष रूप से पर्ल मॉड्यूल के वैश्विक चर सेट करें?

कारण यह मेरे लिए बुरा गंध करता है यह तथ्य है कि यह circumvents encapsulation की तरह है। सिर्फ इसलिए कि इसे पर्ल में कर सकता है, मैं पूरी तरह से निश्चित नहीं हूं कि (मान लीजिए कि वास्तव में मॉड्यूल में गेटर/सेटर जोड़ने जैसे विकल्प हैं)।

+0

ओह, कौन सा मॉड्यूल? –

+2

बस इसके लिए जाओ। अगर वे इसे अस्वीकार करते हैं तो क्या। जीवन में बुरी चीजें होती हैं। –

+1

तो * इसे * encapsulate। और आप इसे संदर्भ के रूप में उपयोग कर सकते हैं: http://stackoverflow.com/questions/1540539/how-do-you-localize-a-number-of-legacy-globals-without-eval – Axeman

उत्तर

8

वैरिएबल सार्वजनिक एपीआई का हिस्सा है, तो यह encapsulation का उल्लंघन नहीं कर रहा है। (यदि ऐसा नहीं है कि एक और बात है।)

मुझे लगता है कि सीधी पहुँच बेहतर है के रूप में यह आप गतिशील scoping का लाभ लेने के लिए अनुमति देता है:

local $Module::varName = 42; 

यह Module कम संभावना का उपयोग अन्य कोड के साथ संघर्ष करता है।

+2

सहमत हैं, मैं 'स्थानीय $ डेटा :: डम्पर :: मैक्सलेवल = 1;' जैसी चीजें करता हूं। – Ether

+0

+1 "सार्वजनिक एपीआई का हिस्सा" को बढ़ा रहा है; यदि ऐसा नहीं है, तो इस कोयली नामित मॉड्यूल के अन्य उपयोगकर्ताओं को अप्रत्याशित व्यवहार मिल सकता है और आपको बुरा दांत – msw

+0

पर बदलना पड़ सकता है, आप वास्तव में "सार्वजनिक एपीआई" पर विचार करेंगे? जो भी पीओडी में है? यदि ऐसा है, तो नहीं, चर पीओडी में नहीं है। – DVK

2

वैश्विक मॉड्यूल चर अतीत में प्रचलित थे, लेकिन आधुनिक पर्ल में एक इंटरफेस के रूप में "खराब रूप" माना जाता था। यह पहचानना महत्वपूर्ण है कि पर्ल अब 22-23 साल पुराना है, और शैलियों और प्रथाओं में बदलाव आया है। :) ध्यान दें कि ऐसे समय होते हैं जब यह अभी भी उपयुक्त है, क्योंकि कुछ चरम विशेषताएं हैं जो पैकेज चर के साथ आती हैं। यह सामान्य रूप से अनुभव और अभ्यास का मामला है कि यह देखने के लिए कि एक अच्छा समाधान क्या हो सकता है।

पैकेज चर के लिए सबसे अच्छा उपयोग समझने के लिए, आपको वास्तव में यह समझने की आवश्यकता है कि local काम करता है। local's perldoc help देखें। स्थानीय आपको पैकेज पैरामीटर जैसे (उदाहरण के रूप में) $My::Variable पैकेज My पैकेज में ले जाने देता है, और इसके dynamically scoped संस्करण बना देता है। आम तौर पर यदि आप $My::Variable जगह में बदलते हैं, तो यह आपके पूरे कार्यक्रम को प्रभावित करेगा, और जारी रहेगा। छोटे कार्यक्रमों के लिए, यह एक बड़ा सौदा नहीं हो सकता है। बड़े लोगों के लिए, यह विनाशकारी साइड इफेक्ट्स हो सकता है। local आपको उस चर में अस्थायी परिवर्तन करने देता है, जो आपके वर्तमान दायरे तक सीमित है। प्रभावी ढंग से

use 5.012; 
use warnings; 

package My; 

our $Variable = 5; 

package main; 

say $My::Variable; # prints 5 
$My::Variable = 7; 
say $My::Variable; # prints 7 
{ # create a new lexical scope 
    local $My::Variable = 10; # create a new dynamic scope for $My::Variable 
           # that will persist to the end of the lexical scope 
    say $My::Variable; # prints 10 
} 
say $My::Variable; # end of the lexical scope for the localized 
        # $My::Variable, so prints 7 again 

, यह आप एक सुरक्षित तरीका में पैकेज चर का उपयोग करने देता है:

यह ऐसे काम करता है। दुर्भाग्यवश, हर कोई स्थानीय के बारे में नहीं जानता, इसलिए वे अक्सर वैश्विक चर को पकड़ते हैं। अच्छा उपयोग दस्तावेज (उदाहरण के लिए, local) हमेशा मदद करता है।

उचित वस्तु encapsulation के साथ एक गेटर/सेटर इस बहुत से रोकता है, लेकिन हमेशा नहीं। स्थानीय वैरिएबल के तरीके को काम करने के लिए, आपको बहुत अधिक काम करना होगा। एक पैकेज वैरिएबल को स्थानांतरित करने में सक्षम होने के बारे में सबसे अच्छी बात यह है कि आप एक डीबग चर के लिए, आसानी से अस्थायी परिवर्तन कर सकते हैं। आम तौर पर, आप की तरह एक पैटर्न क्या करना है:

{ 
    my $current_variable My::get_variable(); 
    $My::set_variable($new_value); 

    # Do code work 

    $My::set_variable($current_variable); 
} 
स्थानीय के साथ

, इस हो जाता है:

{ 
    local $My::Variable = $new_value; 

    # do code work 
} 

(संयोग से, मैं तुम्हें एक ही कारण के लिए भी शाब्दिक चर को यह कर सकता है, इच्छा .. लेकिन आप नहीं कर सकते हैं।) तो, कुछ चीजों के लिए, पैकेज चर समझ में आ सकते हैं। यह इस बात पर निर्भर करता है कि आप इसका उपयोग कैसे करना चाहते हैं।

  • डिबगिंग चर जैसी चीजें
  • वैश्विक विन्यास जो ऐसा नहीं करता/नहीं अक्सर

, बदला जाना चाहिए हालांकि, अगर यह कुछ है कि एक नियमित आधार पर परिवर्तित करने की आवश्यकता है है जैसे

  • नियमित रूप से चर का इस्तेमाल किया (File::Find के लिए भयानक इंटरफ़ेस देखें)
  • अस्थाई विन्यास
  • "ऑब्जेक्ट" चर

असल में, कुछ भी जरूरत है कि एक बार से या दुर्लभ स्थितियों में अधिक संशोधित करने, या अन्यथा एक उत्पन्न वस्तु में समझाया जाना चाहिए, तो मैं पैकेज से बचने चाहते हैं चर।

+0

कह रहा है पर्ल 22 साल का है अब मुझे * मुझे प्राचीन महसूस करता है। :( – Ether

+0

लगभग 6 महीनों में 23 होगा!: डी –

+1

'स्थानीय '* गतिशील * स्कोपिंग प्रदान करता है, न कि * लेक्सिकल * स्कोपिंग। यदि आप ब्लॉक के अंदर से एक सबराउटिन कहलाते हैं तो यह' $ My :: Variable' को 10 के रूप में देखेगा , 7. नहीं। पीछे की ओर, 'स्थानीय' को 'temp' नाम दिया जाना चाहिए था, क्योंकि यह वैश्विक चर के लिए अस्थायी मान प्रदान करता है। –

-2

इनपुट-स्वच्छता/त्रुटि-संभाल नहीं है जो encapsulation के बारे में है?

यदि ऐसी कोई आवश्यकता नहीं है, तो कोई गेटर्स और सेटर्स को लागू करने के खिलाफ बहस कर सकता है, जो sub set_variable { $variable = shift; } जैसे मूर्खतापूर्ण कुछ दिखाई देगा।

आपको लगता है कि set_variable(42) का उपयोग करने के लिए Michael की तुलना में आंखों पर आसान है!

+4

Encapsulation कार्यान्वयन के विवरण छुपा रहा है ताकि यह बिना बदल सके कॉलर जानना। यह एक स्वीकृति है कि हम भविष्य की भविष्यवाणी करने पर चूसते हैं।उदाहरण के लिए, यदि इनपुट स्वच्छता और त्रुटि प्रबंधन महत्वपूर्ण नहीं है * अब * यह बाद में हो सकता है। एक वैश्विक का उपयोग करें और इसमें इसे घुमाने के लिए कोई आसान तरीका नहीं है (आपको टाई का उपयोग करना है, अब आपका कोड धीमा और जटिल है)। या शायद अब सवाल में डेटा वैश्विक है लेकिन बाद में आप इसे प्रति वस्तु चाहते हैं। या शायद आप हर प्रयोग पर एक कार्रवाई करना चाहते हैं? वैश्विक रूप से एक्सपोज़ करना आपकी भविष्यवाणी पर शर्त लगा रहा है कि भविष्य में आपका कोड कैसे विकसित होगा। – Schwern

+0

@Schwern: पूरी जावा दुकानें हैं जिनमें 'मानक व्यवहार में कोई व्यवहार नहीं है' जैसे कुछ "मानक" हैं। यह दर्शाता है कि गेटर्स और सेटर्स के लिए "encapsulation" के लिए बिल्कुल कुछ भी जोड़ने के लिए यह कितना आम है। – Axeman

+0

@ एक्समैन सामान्य रूप से वे एक अच्छा विचार हैं या नहीं, शुद्ध वीओ पर एक्सेसर्स में मूल्य है। कभी-कभी वीओ की आंतरिक संरचना को बदलने का अर्थ होता है; शायद निर्माण समय पर सभी डेटा की गणना करने के लिए यह महंगा या अपर्याप्त है और आप केवल मांग पर ही करना चाहते हैं? शायद आप एक वीओ को प्रॉक्सी या फ्लाईवेट ऑब्जेक्ट बनना चाहते हैं? हो सकता है कि डेटा का एक टुकड़ा बहिष्कृत हो गया हो और आप उपयोगकर्ता को चेतावनी देना चाहते हैं या इसकी पहुंच रिकॉर्ड करना चाहते हैं? सार्वजनिक डेटा सदस्यों के साथ यह संभव नहीं है। एक अच्छी भाषा सार्वजनिक डेटा सदस्य और एक एक्सेसर के बीच कोई वाक्यविन्यास भेद नहीं करके इस समस्या से बचाती है। – Schwern

1

यदि मॉड्यूल एक एक्सेसर प्रदान नहीं करता है, तो एक बनाएं, इसका उपयोग करें, और पैच में भेजें।