2012-11-20 14 views
8

मैं ::-> के साथ उलझन में रहता हूं जब मॉड्यूल से सबराउटिन को कॉल करता है। मुझे पता है कि :: पथ से अधिक संबंधित है और जहां मॉड्यूल/सबराउटिन है और -> ऑब्जेक्ट्स के लिए उपयोग किया जाता है, लेकिन मुझे वास्तव में समझ में नहीं आ रहा है कि मैं दोनों का आदान-प्रदान क्यों कर सकता हूं और यह तत्काल त्रुटियों के साथ नहीं आ रहा है। मेरे पास पर्ल मॉड्यूल हैं जो एक बड़े पैकेज का हिस्सा हैं, उदा। FullProgram::Part1पर्ल मॉड्यूल से तरीकों को कॉल करते समय '::' और '->' काम (प्रकार) का एक-दूसरे से क्यों काम करते हैं?

मैं सिर्फ मॉड्यूल के साथ पकड़ के लिए हो रही के बारे में हूँ, लेकिन अभी भी दिखता जारी आधार पर कर रहा हूँ जब यह पर्ल वस्तुओं की बात आती है, लेकिन मैं गलती से यह कर रहा हूँ:

FullProgram::Part1::subroutine1(); 

के बजाय

तो जब मैं ऑब्स संदर्भ से निपटने के लिए $class/$self का उपयोग करने के बारे में सावधानी बरतता हूं और :: का उपयोग करता हूं तो मैं अपने बालों को खींचकर सोचता हूं कि मेरा हैश रेफ क्यों लगता है गायब करने के लिए। मैंने अपना सबक सीखा है, लेकिन वास्तव में अंतर की व्याख्या करना पसंद करेंगे। मैंने इन पर perldocs और विभिन्न वेबसाइटों को पढ़ा है, लेकिन मैंने दोनों के बीच कोई तुलना नहीं देखी है (Google के लिए काफी कठिन ...) सभी मदद की सराहना की - मैं समझ रहा हूं कि मैं क्या कर रहा हूं!

+0

कुछ अच्छे उत्तरों, चुनने के लिए मुश्किल है, लेकिन धन्यवाद - निश्चित रूप से चीजों को मंजूरी दे दी! – dgBP

उत्तर

7
FullProgram::Part1::subroutine1(); 

जबकि

FullProgram::Part1->subroutine1(); 

पहले तर्क के रूप में पैकेज का नाम के साथ एक ही सबरूटीन कॉल पैकेज FullProgram::Part1 की सबरूटीन subroutine1 एक खाली पैरामीटर सूची के साथ कहता है (ध्यान दें कि यह थोड़ा और अधिक जटिल हो जाता है जब आप उपclassing कर रहे हैं)। इस वाक्य रचना निर्माता तरीकों FYI करें

sub new { 
    my ($class, @args) = @_; 
    ... 
    return bless $thing, $class; 
} 

तरह उपवर्गों की वस्तुओं के निर्माण के लिए वर्ग के नाम की जरूरत है कि द्वारा किया जाता है: पर्ल OO में आप देख $object->method(@args) जो वस्तु (एक धन्य संदर्भ) के बजाय पहले तर्क के रूप में साथ Class::method कॉल पैकेज/वर्ग का नाम। इस तरह की एक विधि में, सबरूटीन इस तरह काम कर सकता था:

sub method { 
    my ($self, $foo, $bar) = @_; 
    $self->do_something_with($bar); 
    # ... 
} 

जो वस्तु के साथ सबरूटीन do_something_with कॉल करेंगे के रूप में पहला तर्क फिर जो दूसरी सूची तत्व आप मूल रूप से method के लिए पारित किया था $bar का मूल्य द्वारा पीछा किया @args में। इस तरह वस्तु स्वयं खो नहीं जाती है।

विधियों को कॉल करते समय विरासत वृक्ष महत्वपूर्ण कैसे होता है, इसके बारे में अधिक जानकारी के लिए, कृपया ikegami's answer देखें!

+2

'$ ऑब्जेक्ट-> विधि (@args)' क्लास :: विधि को कॉल नहीं करता है "। यह विरासत पेड़ में पाए गए 'विधि' नाम की पहली विधि को कॉल करता है। – ikegami

+0

मेरा उत्तर बहुत जटिल किए बिना उस विषय का उल्लेख करने का प्रयास किया और "बस" हटा दिया। धन्यवाद, @ikegami! – memowe

9

वेनिला सब और किसी के बीच कोई अंतर्निहित अंतर नहीं है। यह सब कुछ है कि आप इसे कैसे कहते हैं।


Class::foo('a'); 

यह Class::foo कॉल करेंगे। यदि Class::foo मौजूद नहीं है, तो विरासत का पेड़ चेक नहीं किया जाएगा। Class::foo केवल प्रदत्त तर्क ('a') पारित किया जाएगा।

यह लगभग रूप में एक ही है: my $sub = \&Class::foo; $sub->('a');


Class->foo('a'); 

यह इसके आधार वर्गों में से एक में Class::foo, या foo फोन करेगा अगर Class::foo मौजूद नहीं है। Invocant (-> के बाईं ओर क्या है) एक तर्क के रूप में पारित किया जाएगा।

यह लगभग रूप में एक ही है: my $sub = Class->can('foo'); $sub->('Class', 'a');

0

ऐतिहासिक रूप से, पर्ल न किसी भी OO था। और संकुल से कार्य FullProgram::Part1::subroutine1(); sytax के साथ बुलाया जाता है। या FullProgram'Part1'subroutine1(); वाक्यविन्यास (बहिष्कृत) के साथ भी पहले।

बाद में, उन्होंने -> साइन के साथ ओओपी लागू किया, लेकिन वास्तव में बहुत अधिक नहीं बदला। FullProgram::Part1->subroutine1(); कॉल subroutine1 और FullProgram::Part1 1 पैरामीटर के रूप में चला जाता है। जब आप ऑब्जेक्ट बनाते हैं तो आप इसका उपयोग देख सकते हैं: my $cgi = CGI->new()। अब, जब आप इस ऑब्जेक्ट से कोई विधि कॉल करते हैं, तो बाएं भाग फ़ंक्शन के लिए पहले पैरामीटर के रूप में भी जाता है: $cgi->param('')। यह बताता है कि कैसे param ऑब्जेक्ट प्राप्त करता है जिसे वह बुलाया जाता है (आमतौर पर $self नाम दिया जाता है)। बस। -> ओओपी के लिए हैक है। इसलिए परिणामस्वरूप पर्ल में कक्षाएं नहीं हैं (पैकेज उनके रूप में काम करते हैं) लेकिन ऑब्जेक्ट्स ("ऑब्जेक्ट्स" हैक्स भी हैं - वे स्केलर्स धन्य हैं)।

ऑफटॉप: इसके अलावा आप my $cgi = new CGI; वाक्यविन्यास के साथ भी कॉल कर सकते हैं। यह CGI->new जैसा ही है। वही जब आप print STDOUT "text\n"; कहते हैं। हाँ, बस IOHandle::print() पर कॉल करें।

+1

यह भी उल्लेखनीय है कि '->' विरासत वृक्ष को देखने के लिए perl का कारण बनता है (फिर भी '@ ISA' के माध्यम से एक और हैक)। – friedo

5

दोनों का उपयोग करें!

use Module::Two; 

Module::Two::->class_method(); 

ध्यान दें कि यह काम करता है लेकिन आपको वहां अस्पष्टता के खिलाफ भी सुरक्षा देता है; - संभावना एक रनटाइम त्रुटि में जिसके परिणामस्वरूप या एक वर्ग या उदाहरण बुला

Module::Two()->class_method(); 

(मॉड्यूल में सबरूटीन दो बुला और अपनी वापसी मूल्य पर class_method कॉल करने के लिए कोशिश कर रहा है: सरल

Module::Two->class_method(); 

के रूप में व्याख्या की जाएगी कुछ पूरी तरह से अलग वर्ग में विधि) यदि मॉड्यूल में एक उप दो होता है - ऐसा कुछ जो आपको एक तरफ या दूसरे पर निर्भर नहीं होना चाहिए, क्योंकि यह में से कोई भी कोड का व्यवसाय मॉड्यूल में क्या है।

+1

मजेदार तथ्य के लिए lol +1 – PSIAlt

+0

यहां व्यक्त की गई पार्सिंग अस्पष्टता पर्ल के बारे में मेरी "पसंदीदा" चीजों में से एक है। तथ्य यह है कि कामकाज इतना बदसूरत है मुझे दुखी करता है। – darch

+0

@darch: मुझे नहीं लगता कि यह बदसूरत है। आप "मॉड्यूल :: दो" -> class_method() 'के बारे में क्या सोचते हैं? – ysth