2010-05-29 13 views
8

मेरी वर्तमान नौकरी में मैं पर्ल स्क्रिप्ट का एक सूट बना रहा हूं जो वस्तुओं पर भारी निर्भर करता है। (संभवतः ओओ के करीब होने के लिए हैश पर पर्ल के bless() का उपयोग करके)एक बतख-टाइप की गई भाषा में स्थैतिक-टाइपिंग के पहलुओं को सिम्युलेट करना

अब, इसे डालने का बेहतर तरीका नहीं है, मेरी कंपनी के अधिकांश प्रोग्रामर बहुत स्मार्ट नहीं हैं। इससे भी बदतर, वे दस्तावेज पढ़ने को पसंद नहीं करते हैं और अन्य लोगों के कोड को समझने में कोई समस्या है। काउबॉय कोडिंग यहां गेम है। जब भी उन्हें कोई समस्या आती है और इसे ठीक करने का प्रयास करते हैं, तो वे एक भयानक समाधान के साथ आते हैं जो वास्तव में कुछ भी हल नहीं करता है और आमतौर पर इसे और भी खराब बनाता है।

यह परिणाम मुझे, स्पष्ट रूप से, बतख टाइप भाषा में लिखे गए कोड के साथ भरोसा नहीं करते हैं। एक उदाहरण के रूप में, मुझे उन समस्याओं के साथ बहुत सी समस्याएं दिखाई देती हैं जिन्हें वस्तुओं का दुरुपयोग करने के लिए स्पष्ट त्रुटि नहीं मिल रही है। उदाहरण के लिए, यदि A में सदस्य foo है, और वे instance->goo जैसे कुछ करते हैं, तो वे तुरंत समस्या को नहीं देख पाएंगे। यह एक शून्य/अपरिभाषित मूल्य वापस कर देगा, और वे शायद कारण खोजने में एक घंटे बर्बाद कर देंगे। फिर कुछ और बदलना समाप्त करें क्योंकि उन्होंने मूल समस्या की उचित पहचान नहीं की है।

तो मैं अपनी स्क्रिप्टिंग भाषा रखने के लिए एक तरीके से समझ रहा हूं (इसका तीव्र विकास एक लाभ है) लेकिन एक ऑब्जेक्ट ठीक से उपयोग नहीं होने पर एक स्पष्ट त्रुटि संदेश दें। मुझे एहसास है कि चूंकि संकलन चरण या स्थैतिक टाइपिंग नहीं है, इसलिए त्रुटि को रन टाइम पर होना होगा। मैं इसके साथ ठीक हूं, जब तक उपयोगकर्ता को एक बहुत ही स्पष्ट नोटिस मिलता है कि "इस ऑब्जेक्ट में एक्स नहीं है"

मेरे समाधान के हिस्से के रूप में, मैं नहीं चाहता कि यह आवश्यक हो कि वे जांचें कि क्या इसका उपयोग करने से पहले एक विधि/चर मौजूद है।

भले ही मेरा काम पर्ल में है, मुझे लगता है कि यह भाषा अज्ञेयवादी हो सकती है।

+0

यह देखते हुए कि आप इस माहौल में हैं, यह स्वीकार करते हुए कि आपके सहकर्मियों को यह समझ में नहीं आता है ... ऐसा लगता है कि आप समस्या का हिस्सा हैं! – Stephen

+0

मैं पसंद से पर्ल का उपयोग नहीं कर रहा हूँ। यह या तो प्रबंधन के अनुसार यह या sh था। – Mike

+0

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

उत्तर

15

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

use MooseX::Declare; 

class BankAccount { 
    has 'balance' => (isa => 'Num', is => 'rw', default => 0); 

    method deposit (Num $amount) { 
     $self->balance($self->balance + $amount); 
    } 

    method withdraw (Num $amount) { 
     my $current_balance = $self->balance(); 
     ($current_balance >= $amount) 
      || confess "Account overdrawn"; 
     $self->balance($current_balance - $amount); 
    } 
} 

class CheckingAccount extends BankAccount { 
    has 'overdraft_account' => (isa => 'BankAccount', is => 'rw'); 

    before withdraw (Num $amount) { 
     my $overdraft_amount = $amount - $self->balance(); 
     if ($self->overdraft_account && $overdraft_amount > 0) { 
      $self->overdraft_account->withdraw($overdraft_amount); 
      $self->deposit($overdraft_amount); 
     } 
    } 
} 

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

मूस के साथ, आप वास्तव में आसानी से उपप्रकार बना सकते हैं, ताकि आप सुनिश्चित कर सकें कि आपका इनपुट मान्य है। आलसी प्रोग्रामर इस बात से सहमत हैं: मूस में उपप्रकारों को काम करने के लिए इतना कम किया जाना चाहिए, उन्हें ऐसा करना आसान है! (Cookbook 4 से)

subtype 'USState' 
    => as Str 
    => where { 
      ( exists $STATES->{code2state}{ uc($_) } 
      || exists $STATES->{state2code}{ uc($_) }); 
     }; 

और टाडा, USState अब एक प्रकार का उपयोग कर सकते है! कोई झगड़ा नहीं, कोई मुसब्बर नहीं, और कोड की थोड़ी सी मात्रा। यदि यह सही नहीं है, तो यह एक त्रुटि फेंक देगा, और आपकी कक्षा के सभी उपभोक्ताओं को उस स्ट्रिंग के साथ स्केलर पास करना होगा। यदि यह ठीक है (जो यह होना चाहिए ... सही? :)) वे इसे सामान्य की तरह उपयोग करते हैं, और आपकी कक्षा कचरे से संरक्षित है। वह कितना अच्छा है!

मूस के पास इस तरह की बहुत सी चीजें हैं।

मेरा विश्वास करो। इसकी जांच - पड़ताल करें। :)

+2

मूस के लिए +1 :) – DVK

+0

क्या मूस के पास ऑब्जेक्ट -> {member} को एक त्रुटि में बदलने का कोई तरीका है? मुझे लगता है कि यही ओपी चाहता है। – Schwern

+2

MooseX :: अंदरूनी ओर देखो। इसे $ ऑब्जेक्ट -> {सदस्य} अमान्य बनाना चाहिए, जबकि ऊपर वर्णित सभी एंटीलीड भलाई का उपयोग करने में सक्षम होना चाहिए। –

4

पर्ल में,

  • यह आवश्यक है कि use strict और use warningsclosures बनाकर कोड

  • आप एक लगभग निजी सदस्य चर बनाने के लिए कोशिश कर सकते हैं की 100% में पर कर रहे हैं। http://www.usenix.org/publications/login/1998-10/perl.html में "निजी सदस्य चर, क्रमबद्ध करें" अनुभाग का एक बहुत अच्छा उदाहरण है। वे 100% निजी नहीं हैं लेकिन काफी स्पष्ट नहीं हैं कि जब तक आप वास्तव में नहीं जानते कि आप क्या कर रहे हैं (और उन्हें आपके कोड को पढ़ने और शोध करने के लिए शोध करने की आवश्यकता है) तक पहुंचने के लिए।

  • आप बंद का उपयोग नहीं करना चाहते हैं, तो निम्नलिखित दृष्टिकोण कुछ हद तक अच्छी तरह से काम करता है:

    अपने वस्तु सदस्य चर के सभी (उर्फ पर्ल में हैश कुंजी वस्तु) accessors में लिपटे करें। कोडिंग मानकों पीओवी से कुशलता से ऐसा करने के तरीके हैं। कम से कम सुरक्षित वर्ग वर्ग :: एक्सेसर :: फास्ट। मुझे यकीन है कि मूस के बेहतर तरीके हैं लेकिन मैं मूस से परिचित नहीं हूं।

    निजी-सम्मेलन नामों में वास्तविक सदस्य चर को "छुपाएं" सुनिश्चित करें, उदा। $object->{'__private__var1'} सदस्य चर होगा, और $object->var1() एक गेटर/सेटर एक्सेसर होगा।

    नोट: अंतिम के लिए, कक्षा :: एक्सेसर :: फास्ट खराब है क्योंकि इसके सदस्य चर इन्हें एक्सेसर्स के साथ साझा करते हैं। लेकिन आपके पास बहुत आसान बिल्डर्स हो सकते हैं जो क्लास :: एक्सेसर :: फास्ट की तरह काम करते हैं और "foo" के लिए $ obj -> {'__ private__foo'} जैसे प्रमुख मान बनाते हैं।

    यह उन्हें पैर में खुद को शूटिंग करने से नहीं रोकेगा, लेकिन ऐसा करने के लिए इसे बहुत कठिन बना देगा।

    अपने मामले में, यदि वे $obj->goo या $obj->goo() का उपयोग करते हैं, तो वे कम से कम पर्ल में रनटाइम त्रुटि प्राप्त करेंगे।

    वे निश्चित रूप से $obj->{'__private__goo'} करने के अपने रास्ते से बाहर निकल सकते हैं, लेकिन अगर वे आलसी आलस्य के कारण गोंजो काउबॉय बकवास करते हैं, तो बाद में सही $obj->foo() सही करने से बहुत अधिक काम है।

    आपके पास कोड-बेस का स्कैन भी हो सकता है जो $object->{"_ प्रकार स्ट्रिंग का पता लगाता है, हालांकि आपके विवरण से जो बहुत अधिक निवारक के रूप में काम नहीं कर सकता है।

+3

@ ज्रॉकवे - काफी उचित - मेरे हिस्से पर खराब शब्द। मैं exaggregatrion हटा देंगे। लेकिन जैसा कि मैंने "नाम से निजी" विकल्प में कहा था, खेल का नाम "अच्छी चीज को खराब चीज से कठिन बनाना" है। – DVK

4

आप Class::InsideOut या Object::InsideOut का उपयोग कर सकते हैं जो आपको सही डेटा गोपनीयता प्रदान करता है। एक धन्य हैश संदर्भ में डेटा संग्रहीत करने के बजाय, एक आशीर्वाद स्केलर संदर्भ लेक्सिकल डेटा हैश की कुंजी के रूप में उपयोग किया जाता है। लंबी कहानी छोटी, यदि आपके सहकर्मी $obj->{member} को आजमाते हैं तो उन्हें रन टाइम त्रुटि मिल जाएगी। $obj में उन्हें पकड़ने के लिए कुछ भी नहीं है और एक्सेसर्स को छोड़कर डेटा प्राप्त करने का कोई आसान तरीका नहीं है।

यहां a discussion of the inside-out technique and various implementations है।

+0

मुझे याद है कि कुछ साल पहले अंदरूनी वस्तुओं के बारे में बहुत सी बात हो रही थी और वे नई गर्मी महसूस कर रहे थे, लेकिन इन दिनों उन्होंने रडार को काफी गिरा दिया है। कोई विचार क्यों वे पक्ष से बाहर गिर गए? क्या उनके साथ वास्तविक समस्याएं हैं या क्या वे सिर्फ मूस द्वारा ग्रहण कर रहे थे? –

+0

AFAIK उन मुद्दों में से अधिकांश जो उन्हें समस्याग्रस्त बना चुके हैं, हल हो गए हैं, यह फ़ील्ड हैश जोड़ने के लिए 5.10 (जिसे 5.8 तक बैकपोर्ट किया गया है) की एक महत्वपूर्ण विशेषता थी (उन्हें हैश :: Util :: FieldHash देखें) ताकि उनका उचित समर्थन किया जा सके। हो सकता है कि अब कार्यान्वयन के मुद्दों के बारे में बात करने लायक नहीं है? – Schwern

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