2010-10-20 8 views
7

exists फ़ंक्शन unexpectedly autovivify entries हैश में कर सकते हैं। मुझे लगता है यह एक बग हैमेरा निरंतर संशोधित क्यों 'मौजूद' है?

use strict; 
use warnings; 
use Data::Dump 'dump'; 

use constant data => { 
         'foo' => { 
            'bar' => 'baz', 
           }, 
         'a' => { 
            'b' => 'c', 
           } 
        }; 

dump data; # Pre-modified 

print "No data for 'soda->cola->pop'\n" unless exists data->{soda}{cola}{pop}; 

dump data; # data->{soda}{cola} now sprung to life 

आउटपुट

{ a => { b => "c" }, foo => { bar => "baz" } } 
No data for 'soda->cola->pop' 
{ a => { b => "c" }, foo => { bar => "baz" }, soda => { cola => {} } } 

:

मुझे क्या आश्चर्य है कि इस व्यवहार के रूप में अच्छी तरह से स्थिरांक के लिए खत्म हो जाता है। क्या यह कुछ 5.10.1-विशिष्ट है, या पर्ल के अन्य संस्करण समान व्यवहार करते हैं?

+4

"नो [ऑटोविविफिकेशन] (http://search.cpan.org/perldoc?autovivification)" का उपयोग करके आप किसी भी शब्दावली के लिए ऑटोविविफिकेशन बंद कर सकते हैं। – rafl

+0

मेरा प्रश्न 'अस्तित्व' के साथ स्थिरांक के उत्परिवर्तनीय व्यवहार के बारे में अधिक था, इसके बजाय मैं इससे कैसे बच सकता था। – Zaid

+3

स्थिरांक के साथ काम करते समय, याद रखें कि 'निरंतर पीआई => 3.14' का उपयोग 'उप पीआई() {3.14}' और' निरंतर डेटा => {...} '' '{my $ data = { ...}; उप डेटा() {$ डेटा}} ' –

उत्तर

15

यह दस्तावेज व्यवहार है। perldoc constant का कहना है:

हालांकि एक संदर्भ एक निरंतर के रूप में घोषित किया जा सकता है, संदर्भ डेटा जो हो इस कोड है, जैसा कि बदल सकते हैं करने के लिए जा सकते हैं।

use constant ARRAY => [ 1,2,3,4 ]; 
print ARRAY->[1]; 
ARRAY->[1] = " be changed"; 
print ARRAY->[1]; 

यह संदर्भ है कि स्थिर है, क्या नहीं यह को संदर्भित करता है।

+0

क्या आप समझा सकते हैं कि क्यों पर्ल ने 'निरंतर var => 50 का उपयोग करने के लिए' स्केलर असाइनमेंट में निरंतर आइटम को संशोधित नहीं किया जा सकता है '; var = 40; ' – Zaid

+2

क्योंकि आप निरंतर बदलने की कोशिश कर रहे हैं। और आप ऐसा नहीं कर सकते। Constants हैं ... अच्छी तरह से ... निरंतर। यह उनका पूरा बिंदु है। आपके द्वारा निरंतर स्टोर किए जाने वाले स्केलर मान को बदला नहीं जा सकता है। लेकिन जब आप हैश संदर्भ से स्थिर बनाते हैं (जैसा कि आपके उदाहरण में है) यह संदर्भ है जो तय किया गया है, न कि आपके पास संदर्भ वाला डेटा। संदर्भ स्केलर मान है जो निरंतर संग्रहित होता है। –

+0

अच्छी चीजें, इच्छा है कि मैं यह जवाब +2 कर सकता हूं। – Zaid

9

शायद आप "सत्य" स्थिरांक बनाने के लिए Readonly का उपयोग करना चाहते हैं।

constant प्राग्मा का उपयोग करके बनाए गए स्थिरांक वास्तव में inlinable subroutines हैं। इसका मतलब है कि संकलन समय पर उचित स्केलर स्थिरता कुछ सबराउटिन कॉल के स्थान पर सीधे डाली जाती है। यदि निरंतर संदर्भ है, तो कुछ भी आपको उस डेटा को बदलने से रोकता है जो इसे इंगित करता है।

+0

एक स्थिर हैशर एक स्केलर निरंतर है? – Zaid

+1

मुझे नहीं पता कि यह प्रश्न का उत्तर कैसे है? – ysth

+0

रीडोनली की बजाय डेटा :: लॉक (विशेषता :: कॉन्स्टेंट का हिस्सा) जैसे कुछ का उपयोग करें। – MkV

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