2011-05-24 14 views
10

मैं एक पैकेज My::Pkg कहा जाता है कहते हैं, और कहा कि पैकेज नई वस्तुओं का दृष्टांत के लिए एक ->new(...) वर्ग विधि है:पर्ल में, क्या पैकेज के समान नाम के साथ सबराउटिन बनाने में कोई हानि है?

package My::Pkg; 

sub new {bless {@_[1..$#_]} => $_[0]} 

वहाँ निम्नलिखित सबरूटीन को परिभाषित करने में कोई नुकसान है:

sub My::Pkg {@_ ? My::Pkg::new('My::Pkg', @_) : 'My::Pkg'} 

तो है कि किसी को लिख सकते हैं:

my $obj = My::Pkg one => 1, two => 2; 

के बजाय:

my $obj = My::Pkg->new(one => 1, two => 2); # which still works, but is longer 

मुझे पैकेज-नाम-कन्स्ट्रक्टर-सबराउटिन विधि की चतुरता पसंद है, लेकिन मुझे यह जानने में दिलचस्पी है कि इस तकनीक के लिए कोई छुपा गेटचा है या नहीं, जिस पर मैंने सोचा नहीं है।


अद्यतन:

विरासत, ठीक से काम करता के रूप में उदाहरण के यहाँ से दिखाया गया है:

{package a; sub new {say "a::new [@_] ", $_[0]->init}} 
{package b; our @ISA = 'a'; sub init {"(b::init [@_])"}} 
{package a::b; our @ISA = 'b';} 

sub a::b {print "absub [@_], "; 'a::b'} 

# a::b() called with no args, returns 'a::b', which then becomes 'a::b'->new(...) 
a::b->new;   # absub [], a::new [a::b] (b::init [a::b]) 
a::b->new(1, 2, 3); # absub [], a::new [a::b 1 2 3] (b::init [a::b])  

# no call to `a::b()` but otherwise the same: 
'a::b'->new;   # a::new [a::b] (b::init [a::b]) 
'a::b'->new(1, 2, 3); # a::new [a::b 1 2 3] (b::init [a::b]) 

new a::b::;   # a::new [a::b] (b::init [a::b]) 
new a::b:: 1, 2, 3; # a::new [a::b 1 2 3] (b::init [a::b]) 

दिलचस्प बात यह है केवल एक चीज है कि अब तक अलग है कि निम्नलिखित 2 लाइनों वाक्यविन्यास त्रुटियों बन रहा है:

new a::b; 
new a::b 1, 2, 3; 

इसी कारण से एक वाक्यविन्यास त्रुटि है some_undefined_sub some_defined_sub; एक है।

यदि new सबराउटिन परिभाषित किया गया है, तो इसे new(a::b(...)) के रूप में पार्स किया गया है जो दो आसन्न बेवकूफ सबराउटिन के लिए सामान्य है।

व्यक्तिगत रूप से, मैं new a::b में सिंटेक्स त्रुटि बनने के साथ ठीक हूँ, स्पष्ट संस्करण new a::b:: हमेशा tchrist काम आते हुए नीचे की ओर इशारा रूप में काम करेंगे।

+0

साफ दिखता है। अगर कुछ विफल होना था, तो यह 'some_sub मेरा :: पीकेजी ए => 1, बी => 2; 'होगा। यह नहीं है – ikegami

+0

@ikegami: यह निश्चित रूप से ** DOES ** विफल रहता है: 'उप एक्स :: वाई {मर" एक्स :: वाई() जिसे \ n "} उप एक्स :: वाई :: नया {चेतावनी" एक्स :: वाई :: नया() कहा जाता है \ n "} उप नया {मर" मुख्य :: नया() "} $ ए = नया एक्स :: वाई" व्यवसाय "कहा जाता है; चेतावनी देते हैं कि "$ एक प्राप्त हुआ"; 'मर जाएगा ... क्योंकि यह' मुख्य :: नया (एक्स :: वाई ("व्यवसाय")) 'को ठीक से' एक्स :: वाई :: नया ("एक्स: : वाई "," व्यवसाय ")) 'एक विधि के रूप में। इसके अलावा, subroutine कॉल विरासत का सम्मान नहीं करता है जैसा ओओ दुनिया में अनिवार्य माना जाता है। – tchrist

+0

यह बुरा है कि 'नया एक्स :: वाई "व्यवसाय" अचानक' एक्स :: वाई-> नया ("व्यवसाय") '- * से कुछ अलग है जिसका अर्थ है * बीटीडब्ल्यू वास्तव में अब' एक्स :: वाई() - > 'एक्स :: वाई :: नया ("एक्स :: वाई", "व्यवसाय") के बजाय नया ("व्यवसाय") 'हर कोई सोचता है कि इसका मतलब है। – tchrist

उत्तर

7

कि है ठीक क्यों

$thingie = new Some::Class one => 1, two => 2; 

या

$thingie = new Some::Class:: 
       one => 1, 
       two => 2, 
      ; 

मौजूद है, तो बस का उपयोग करें।

लेकिन हाँ, मुझे लगता है कि आप खुद को पूरी तरह से परेशानी में डाल देंगे, क्योंकि मैं दुनिया में एकमात्र व्यक्ति हूं जो पैकेज-कोट को परेशान करता है। मेरे पास अभी मेरी पुरानी समस्या-परीक्षण कोड को खोदने के लिए समय नहीं है, लेकिन मुझे पूरा यकीन है कि अगर आप जिस सड़क पर बोल रहे हैं, वह अंततः आपको रोएगा।

+0

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

+0

विधि को आमंत्रित करने और सबराउटिन को कॉल करने के तरीके में एक बड़ा अंतर है: ** विरासत **। विधि कॉल का उपयोग न करके, आप ओओ डिजाइन के साथ तोड़ रहे हैं। पर्ल में सभी तरह की अजीबता है ताकि 'कुछ :: कक्षा' का अर्थ वास्तव में 'कुछ :: कक्षा "' है, और यही वह है जो लोग इसे करने की उम्मीद कर रहे हैं। यदि आप पैकेज के नाम से कोई फ़ंक्शन बनाते हैं, तो क्लास विधि कॉल करने का प्रयास करते समय आप पूरी तरह से नली लेंगे, क्योंकि आप इसके बजाय गूंगा फ़ंक्शन को कॉल करेंगे। और लोकप्रिय कार्गो-पंथ मिथक के विपरीत, 'मेथोड क्लास :: ARGLIST' के साथ जो कुछ भी अस्पष्ट है, वहां बिल्कुल कुछ भी नहीं है। – tchrist

+0

ऊपर दिए गए प्रश्न का अद्यतन देखें, विरासत ठीक काम करती है। –

4

"मुझे यह जानने में दिलचस्पी है कि इस तकनीक के लिए कोई छिपी हुई गठजोड़ है जिसे मैंने नहीं सोचा है।"

मुझे लगता है कि एक छुपा गॉचा स्थिरता की कमी है जिसमें अधिकांश ओओपी लैंग्स रचनाकारों को परिभाषित करते हैं। जाहिर है, पर्ल को अपने टीएमटीओटीडीआई दर्शन पसंद है, लेकिन किसी को बाद में अपना कोड बनाए रखना है जब/यदि आप आसपास नहीं हैं तो यह समझने में अधिक समय लग सकता है कि आपका कोड क्या कर रहा है।

इसके अलावा, यदि आप एक और कन्स्ट्रक्टर जोड़ना चाहते हैं तो क्या होगा?मैंने कुछ वर्गों को देखा है जहां नामक रचनाकार हैं: नया, new_from_file, आदि शायद सबसे अच्छा डिज़ाइन नहीं है, लेकिन यह स्पष्ट करता है कि एक वस्तु एक अद्वितीय तरीके से बनाई गई थी।

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