2011-10-19 10 views
6

तो मैं अपने Moosey व्यापार के बारे में जा रहा था और मैं हे सोचा मैं कहाँ, संख्या का उपयोग कर रहा इन नंबरों यह स्पष्ट क्या मतलब है या मामले में वे बाद मेंउप-वर्ग अपने माता-पिता के स्थिरांक का उत्तराधिकारी क्यों नहीं करता है?

तो बदल बनाने के लिए इन स्थानों में एक निरंतर उपयोग करने के लिए अच्छा अभिभावक वर्ग में मैंने मानक 'उपयोग निरंतर'

package Parent; 
    use constant { 
     NO_LEVEL => 0, 
     MY_LEVEL => 1, 
     YOUR_LEVEL => 2, 
    }; 

package Child; 
extends 'Parent'; 

#just to demonstrate that child can or cannot access the constant 
sub printMyLevel{ 
print MY_LEVEL; 
} 

लेकिन बाल वर्ग माता-पिता में सेट स्थिरांक से अवगत नहीं है! doh!

मुझे लगता है कि मुझे यह काम करने के लिए कुछ मूस जादू करना है, या पूरी तरह से कुछ और करने के लिए। इस मुद्दे पर मेरी खोज ने कोई परिणाम नहीं खींचा =/

उत्तर

3

चूंकि स्थिरांक subroutines हैं और आप उन्हें बिट को पहले से ही मौत के रूप में बुलाकर विरासत प्राप्त कर सकते हैं, यहां चीजों पर एक अलग स्पिन है।

क्या आप जानते हैं आप केवल एक ही फाइल में काम कर रहे हैं, तो आप पुल संकुल को शाब्दिक स्थिरांक का उपयोग कर सकते हैं:

package Parent; 
    our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL); 
    *NO_LEVEL = \0; # this split declaration installs aliases to numbers 
    *MY_LEVEL = \1; # into the lexicals. since numbers are constants 
    *YOUR_LEVEL = \2; # to perl, the aliased names are also constants 

package Child; 

# just to demonstrate that anything below can access the constants 
sub printAll { 
    print "$NO_LEVEL $MY_LEVEL $YOUR_LEVEL\n"; 
} 

Child->printAll; # 0 1 2 

eval {$NO_LEVEL = 3} or print "error: [email protected]\n"; 
# error: Modification of a read-only value attempted at ... 

आप पर्ल की जरूरत नहीं है जब लगातार करने के लिए बताए मरने के लिए, our घोषणा थोड़ा आसान हो जाता है (और हो सकता है एक my):

our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL) = (0, 1, 2); 

, जबकि अभी भी एक छोटे से जादू के साथ संक्षिप्त सिंटैक्स का उपयोग आप निरंतर प्रकृति वापस ला सकता है:

0,123,
my $constant = sub {Internals::SvREADONLY($_[$_], 1) for 0 .. $#_}; 

package Parent; 
    $constant->(our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL) = (0, 1, 2)); 

package Child; 

# just to demonstrate that anything below can access the constants 
sub printAll { 
    print "$NO_LEVEL $MY_LEVEL $YOUR_LEVEL\n"; # interpolates :) 
} 

Child->printAll; # 0 1 2 

eval {$NO_LEVEL = 3} or print "error: [email protected]\n"; 
# error: Modification of a read-only value attempted at ... 

आप निश्चित रूप से $constant coderef छोड़ देते हैं और जादू इनलाइन कर सकते हैं:

package Parent; 
    Internals::SvREADONLY($_, 1) 
     for our ($NO_LEVEL, $MY_LEVEL, $YOUR_LEVEL) = (0, 1, 2); 
+0

+1 होने के लिए +1। इससे वास्तव में मुझे स्थिति को समझने में मदद मिली। धन्यवाद एरिक! – qodeninja

10

कॉन्स्टेंट सबराउटिन हैं।

{ 
    package Parent; 
    use Moose; 
    use namespace::autoclean; 

    use constant { 
     NO_LEVEL => 0, 
     MY_LEVEL => 1, 
     YOUR_LEVEL => 2, 
    }; 
    __PACKAGE__->meta->make_immutable; 
}; 

{ 
    package Child; 
    use Moose; 
    use namespace::autoclean; 

    extends 'Parent'; 

    sub printMyLevel { 
     my $self = shift; 
     my $class = ref $self; 

     print $class->MY_LEVEL; 
    } 
    __PACKAGE__->meta->make_immutable; 
} 

package main; 

my $child = Child->new; 
$child->printMyLevel; 

ध्यान रखें कि स्थिरांक एक खाली प्रोटोटाइप के साथ सबरूटीन्स हैं। perl संकलन के दौरान इनलाइन करने के लिए इसका लाभ उठाता है। हालांकि, विधि कॉल प्रोटोटाइप की उपेक्षा करते हैं, और इसलिए इस तरह से प्राप्त विरासत स्थिरांक को रेखांकित नहीं किया जाएगा।

+0

क्यों आप अपने पैकेज पर बाहरी {} रख सकता हूं?मैंने यह करना शुरू कर दिया और किसी ने मुझे परेशान किया कि यह आवश्यक नहीं था। अनुलेख मैं सीधे बाल वर्ग में स्थिरांक तक पहुंच बनाना चाहता हूं, ऐसा लगता है कि मुझे $ self-> कॉन्स्टेंट सही उपयोग करना है? – qodeninja

+1

@nodebunny मैंने पैकेज को एक दायरे में संलग्न किया क्योंकि यह सब एक ही फाइल में है। चूंकि यह कक्षा डेटा है, इसलिए मैं इसे स्पष्ट करना चाहता हूं। जाहिर है, '$ स्वयं-> कॉन्स्टेंट' काम करेगा। –

+0

दिलचस्प, यह एक perl idiom की तरह लगता है। फिर फिर मैंने वास्तव में अभी तक ब्लॉक के विचार को प्राप्त किया है। {} <== एक ब्लॉक हाँ है? पूर्ण उदाहरण के लिए +1। – qodeninja

4

उन्हें एक विधि के रूप में कॉल करें।

sub printMyLevel{ 
    my ($self,) = $_; 
    print $self->MY_LEVEL; 
} 
+0

+1 पहले स्वयं को $ self-> स्थिर – qodeninja

6

यह वास्तव में, documentation में बताया गया है, तो केवल गुजर में:

"स्थिरांक पैकेज वे में परिभाषित कर रहे हैं के हैं एक निरंतर एक और पैकेज में परिभाषित करने का उल्लेख करने के लिए, पूर्ण निर्दिष्ट करें। पैकेज नाम, Some::Package::CONSTANT में। कॉन्स्टेंट को मॉड्यूल द्वारा निर्यात किया जा सकता है, और इसे Some::Package->CONSTANT या $obj->CONSTANT के रूप में भी कहा जा सकता है, जहां $objSome::Package का उदाहरण है। उप-वर्ग अपने स्वयं के स्थिरांक को ओवरराइड करने के लिए परिभाषित कर सकते हैं उनके बेस क्लास में। "

+0

समझाएगा ताकि मैं माता-पिता :: कॉन्स्टेंट भी कर सकूं? मुझे लगता है कि मुझे यह बेहतर पसंद है। मैं सीपीएएन/मूस डॉक्स में देख रहा था कि ऐसा करने के लिए एक मूस रास्ता था लेकिन यह भी काम करता है। दस्तावेज़ – qodeninja

+0

'माता-पिता :: कॉन्स्टेंट' के लिए +1 आपको बाल कक्षाओं में इसे ओवरराइड करने की अनुमति नहीं देगा। यह सब आप क्या चाहते हैं उस पर निर्भर करता है। –

+1

@ शिनान: दूसरी ओर, 'अभिभावक :: कॉन्स्टेंट' का लाभ यह है कि इसे संकलित समय पर हल किया जा सकता है। –

2

विरासत विधियों कॉल ($x->m), अवधि को प्रभावित करता है।

+0

+1 एक पूर्ण उत्तर के लिए शाश्वत ikegami – qodeninja

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