2012-06-13 23 views
5

मैं पर्ल में polymorphism कैसे काम करता है इस बारे में एक स्पष्टीकरण को समझने में असमर्थ हूं। मैं समझता हूं कि बहुरूपता का अर्थ क्या है लेकिन मैं यह पता लगाने की कोशिश कर रहा हूं कि यह आंतरिक रूप से perl के भीतर कैसे काम करता है। क्या कोई मुझे कुछ दस्तावेज बता सकता है जो इसे समझाता है। मेरे द्वारा किए गए सभी Google खोजों ने मुझे उदाहरण दिया है कि बहुरूपता क्या है, लेकिन यह नहीं कि यह कैसे काम करता है।पर्ल पॉलीमोर्फिज्म कैसे काम करता है?

+0

आंतरिक कार्यान्वयन, या वाक्यविन्यास/उपयोग? पर्ल ओओपी के लिए – djechlin

उत्तर

14

जब किसी ऑब्जेक्ट या क्लास पर method is invoked, पर्ल यह देखने के लिए देखता है कि वह विधि सीधे कक्षा द्वारा प्रदान की जाती है या नहीं।

क्योंकि classes are simply Perl packages, यह केवल एक subroutine &Class::method के अस्तित्व की तलाश करने का विषय है।

तो ऐसी कोई सबरूटीन पाया जाता है, पर्ल एक ही पैकेज में @ISA सरणी (अर्थात @Class::ISA) जो वर्ग के लिए आधार वर्ग की एक सूची है की जांच करता है, और हर पैकेज/वर्ग है कि वहाँ में प्रकट होता है के लिए एक ही जांच करता है।

बदले में से प्रत्येक कक्षा में @ISA सरणी हो सकती है, इसलिए खोज रिकर्सिव है।

अंत में, यदि विधि इस विधि से कहीं भी नहीं पाई जाती है, तो पर्ल एक विशेष पैकेज UNIVERSAL में एक subroutine &UNIVERSAL::method के लिए देखता है।

इस बिंदु पर एक विफलता AUTOLOAD प्रणाली का आह्वान करने के लिए जारी है, लेकिन यह वास्तव में बहुरूपता के सिद्धांत से परे है।

एक उपयुक्त मिलान विधि खोजने में विफलता कहीं भी अपवाद उठाती है।

0

यह अच्छी तरह से विरासत आधारित पॉलीमोर्फिज्म के अनुरूप है और कुछ विचार देता है कि पर्ल विशेष रूप से क्या करता है। मैंने हमेशा अध्याय 12.5 का उपयोग किया है। इन चीजों के संदर्भ के रूप में कक्षा विरासतProgramming Perl में।

+0

, मुझे हमेशा O'Reilly से "पर्ल ऑब्जेक्ट्स, रेफरेंस, और मॉड्यूल सीखना" पसंद आया: http://shop.oreilly.com/product/9780596004781.do – David

7

Object Oriented Perl से अध्याय 7, डेमियन कॉनवे, मैनिंग (2000) को पॉलिमॉर्फिज्म कहा जाता है। दस पेज

सलाह दी जानी चाहिए कि, यदि आप सी ++ या जावा या सी # या इसी तरह से आ रहे हैं, तो पर्ल में "बहुरूपता" के बारे में जानने के लिए इतना कुछ नहीं है। मैं यह भी कहूंगा कि बहुरूपता की अवधारणा पर्ल में उनके मुकाबले चीजों को और जटिल बनाती है।

मुझे लगता है कि एक पर्ल प्रोग्रामर को यह समझने का प्रयास करना चाहिए कि विधि लुकअप कैसे काम करता है। जवाब है: @ISA पैकेजों के सरणी के माध्यम से गहराई-प्रथम रिकर्सिव स्कैनिंग।

एक उदाहरण, चलिए $o->bla करते हैं। हमारे $o को A पैकेज में आशीर्वाद दिया गया है, जिसमें bla का कार्यान्वयन नहीं है। लेकिन यह पहले B और फिर C (@ISA = ('B', 'C')) से विरासत में मिलता है। तो चलिए पहले B में लुकअप करें। यह विधि को परिभाषित नहीं करता है। यदि उसके माता-पिता कक्षाएं थीं, तो हम वहां अपना लुकअप जारी रखेंगे। लेकिन ऐसा नहीं है। तो अब हम C देखें, और सौभाग्य से इसमें विधि है, अन्यथा यह एक रनटाइम त्रुटि होगी, क्योंकि अंतिम उपाय का पैकेज, UNIVERSAL, bla को परिभाषित नहीं करता है।

4

एक वस्तु विधि कॉल मूल रूप से एक अनुकूलित * निम्न में से संस्करण है:

my $class = ref($_[0]); 
my @isa = mro::get_linear_isa($class); 
for my $pkg (@isa) { 
    if (exists(&{$pkg.'::'.$method_name})) { 
     return &{$pkg.'::'.$method_name}; 
    } 
} 

ref वस्तु के साथ जुड़े वर्ग का नाम हो जाता है। कक्षा ऑब्जेक्ट के चर में संग्रहीत है।

$ perl -MDevel::Peek -e'my $o = {}; Dump($o); bless($o, "SomeClass"); Dump($o);' 
SV = IV(0x9e4ae0c) at 0x9e4ae10 
    REFCNT = 1 
    FLAGS = (PADMY,ROK) 
    RV = 0x9e317d0 
    SV = PVHV(0x9e36808) at 0x9e317d0 
    REFCNT = 1 
    FLAGS = (SHAREKEYS) 
    ARRAY = 0x0 
    KEYS = 0 
    FILL = 0 
    MAX = 7 
    RITER = -1 
    EITER = 0x0 
SV = IV(0x9e4ae0c) at 0x9e4ae10 
    REFCNT = 1 
    FLAGS = (PADMY,ROK) 
    RV = 0x9e317d0 
    SV = PVHV(0x9e36808) at 0x9e317d0 
    REFCNT = 1 
    FLAGS = (OBJECT,SHAREKEYS)  <---- 
    STASH = 0x9e323d0 "SomeClass" <---- 
    ARRAY = 0x0 
    KEYS = 0 
    FILL = 0 
    MAX = 7 
    RITER = -1 
    EITER = 0x0 

get_linear_isa उसमें नामित संकुल की @ISA पैकेज $class में @ISA पर आधारित है, और।

चूंकि वर्ग का नाम ऑब्जेक्ट में है और चूंकि पर्ल रन-टाइम पर अपनी प्रतीक तालिका जांच सकता है, इसलिए पॉलिमॉर्फिज्म प्रदान करने के लिए वर्चुअल विधि तालिका की आवश्यकता नहीं है।

* — यह कैश क्लास $ वर्ग के लिए विधि $ method_name प्रदान करता है। इसके अलावा, यह निश्चित रूप से पूरे रैखिक आईएसए की गणना नहीं करता है, लेकिन आवश्यकतानुसार।

1

पॉलिमॉर्फिज्म केवल यह विचार है कि विभिन्न प्रकार की वस्तुओं का नाम उसी नाम की विधि कॉल का जवाब देता है। पर्ल जैसे कमजोर टाइप की गई भाषाएं "निहित रूप से बहुलक" हैं।

उदाहरण के लिए, एक CGI वस्तु, एक Apache2::Request वस्तु, और एक Plack::Request वस्तु सब एक param विधि है कि HTTP अनुरोध के मापदंडों वापस आ जाएगी है। मैं एक ऐसा फ़ंक्शन लिख सकता हूं जो किसी ऑब्जेक्ट को पैरामीटर के रूप में स्वीकार करता है, और उस ऑब्जेक्ट पर param विधि को कॉल करें, और यह जानने के बिना HTTP अनुरोध पैरामीटर प्राप्त करें कि यह किस प्रकार की ऑब्जेक्ट है।

मजबूत टाइप की गई भाषाएं इस तरह से काम नहीं करतीं क्योंकि उनके कार्य उनके पैरामीटर के डेटा प्रकार निर्दिष्ट करते हैं। मैं Dog के ऑब्जेक्ट के साथ Java में किसी फ़ंक्शन को कॉल नहीं कर सकता अगर यह Cat में से किसी एक की अपेक्षा कर रहा था। इसलिए दृढ़ता से टाइप की गई भाषाओं को बहुरूपता की अनुमति देने के लिए विशेष तंत्र बनाना है।

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