2008-11-04 12 views
7

सरणी में मान होने की संख्या की गणना करने के लिए यहां कुछ सरल पर्ल है। यह बिना किसी चेतावनी के चलाता है।पर्ल ऑटो-प्रारंभिक चर कब करता है?

use warnings; 
use strict; 

my @data = qw(1 1 2 3 4 5 5 5 9); 
my %histogram; 
foreach (@data) 
{ 
    $histogram{$_}++; 
} 

पाश शरीर

$histogram{$_} = $histogram{$_} + 1; 

पर्ल ने चेतावनी दी है "इसके अलावा में अप्रारंभीकृत मूल्य का प्रयोग करें" में बदल दिया जाता है।

हुड के नीचे क्या चल रहा है? ++ ऑपरेटर के लिए ऑपरेंड के रूप में आपूर्ति किए जाने पर और ऑपरेटर के साथ अनियंत्रित होने पर मूल्य प्रारंभ क्यों किया जाता है?

उत्तर

14

+ ऑपरेटर बाएं और फॉर्म के दाईं ओर दोनों रूपों का मूल्यांकन करता है, फिर दोनों का योग देता है। हैश कॉल मूल्यांकन में कोई विशेष संदर्भ नहीं दिखता है।

++ ऑपरेटर कुछ विशेष जादू में बनाया गया है perlop मैनपेज से हवाला देते हुए, ++ ऑपरेटर के बारे में:।

"undef" हमेशा संख्यात्मक रूप में व्यवहार किया जाता है, और विशेष रूप से पहले 0 के लिए बदल गया है वृद्धि (ताकि एक अपरिफ मूल्य की पोस्ट-वृद्धि "अंडेफ" की बजाय 0 लौटाएगी)।

संपादित: अंतर पर विस्तार से बता दें ++ जगह में मूल्य परिवर्तन, + बस इनपुट के रूप में अपने तर्कों लेता है। जब + एक अपरिभाषित मान देखता है, आम तौर पर कुछ गलत हो गया है, लेकिन ++ के लिए, आपके हैश हेरफेर उदाहरण बहुत आम है - उपयोगकर्ता हर समय जांच और प्रारंभ करने के बजाय, 0 के रूप में अनावश्यक व्यवहार करना चाहता है। तो ऐसा लगता है कि इन ऑपरेटरों को इस तरह से इलाज करना समझ में आता है।

7

ऐसा नहीं है कि पर्ल आवश्यक रूप से मूल्यों को प्रारंभ करता है, लेकिन यह हमेशा उनके बारे में चेतावनी नहीं देता है। इसके लिए नियम के बारे में सोचने की कोशिश न करें क्योंकि आपको हमेशा अपवाद मिलेंगे, और जब आपको लगता है कि आपने यह पता लगाया है, तो पर्ल का अगला संस्करण आपको चेतावनियों को बदल देगा।

इस मामले में, जैसा कि हरलेकिन ने कहा, ऑटो-वृद्धि ऑपरेटर के पास एक विशेष मामला है।

0

जैसा कि ब्रायन ने उल्लेख किया है: यह अभी भी करता है, यह आपको चेतावनी देता है। चेतावनियां आपको उन प्रभावों के बारे में बताती हैं जिनके बारे में आप इरादा नहीं कर सकते हैं।

आप $histogram{$_} के मान के लिए पूछ रहे हैं, इसमें 1 जोड़कर और फिर उसी स्लॉट को असाइन कर रहे हैं।

my $hash_ref = $hash_for{$key_level_1}; 
$hash_ref->{$key_level_2} = $value; 

के रूप में यह यहाँ है::

$hash_for{$key_level_1}{$key_level_2} = $value; 

जादू शायद अनुकूलन की तरह काम नहीं करता है यह उसी तरह है कि मैं autovivification यहाँ काम करने की उम्मीद नहीं होता है। और संकलक को अनुकूलित करने से पता चलता है कि a = a + 1a++ जैसा ही है, इसलिए असेंबली भाषा में एक वृद्धि ऑपरेटर था, यह उस मूल्यवान निर्देश का उपयोग कर सकता था कि इसे पहले मान को संरक्षित करने के लिए आवश्यक था, और फिर इसे ओवरराइट करना क्योंकि यह नहीं है वास्तव में जरूरत नहीं है।

ऑप्टिमाइज़ेशन प्रत्येक रन में बेहतर प्रदर्शन के लिए एक बार अतिरिक्त जांच और ओवरहेड होता है। लेकिन एक गतिशील भाषा में कोई गारंटी नहीं है कि आप उसी दर पर ओवरहेड नहीं जोड़ रहे हैं, अन्यथा आप इसे कम करने की कोशिश कर रहे हैं।

+0

जबकि चेतावनियां सीधे निर्माण को तोड़ती नहीं हैं, फिर भी उन्हें ध्यान दिया जाना चाहिए। – Svante

7

कुछ ऑपरेटर जानबूझकर आपकी सुविधा के लिए "अनियमित" चेतावनी को छोड़ देते हैं क्योंकि उन्हें आमतौर पर उन स्थितियों में उपयोग किया जाता है जहां बाएं या केवल ऑपरेंड के लिए 0 या "" डिफ़ॉल्ट मान होता है।

ये हैं: ++ और - (या तो पूर्व या पोस्ट), + =, - =,। =, | =,^=, & & =, || =।

ध्यान दें कि इनमें से कुछ गलती से उपयोग किए जाने पर चेतावनी देते हैं: http://perl5.git.perl.org/perl.git/blob/HEAD:/t/op/assignwarn.t में TODO चिह्नित परीक्षण देखें।

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