2015-11-18 9 views
9

मेरा परीक्षण इस प्रकार है:क्या कोई बता सकता है कि पर्ल इस तरह से व्यवहार क्यों करता है (परिवर्तनीय स्कॉइंग)?

use strict; 
use warnings; 

func(); 
my $string = 'string'; 
func(); 

sub func { 
    print $string, "\n"; 
} 

और परिणाम है:

Use of uninitialized value $string in print at test.pl line 10. 

string 

पर्ल पहले यह परिभाषित किया गया है एक समारोह कॉल करने के लिए अनुमति देता है। हालांकि जब फ़ंक्शन कॉल के बाद ही घोषित एक चर का उपयोग करता है, तो चर को अपरिभाषित प्रतीत होता है। क्या यह व्यवहार कहीं दस्तावेज है? धन्यवाद!

+3

* हमेशा * 'सख्त उपयोग करें; चेतावनियों का प्रयोग करें; '! – Biffen

+0

ओह या मैं वास्तव में उन परीक्षणों में मेरी परीक्षा फाइल में है। मैं इसे संपादित करूंगा। धन्यवाद। – darkgrin

उत्तर

12

my के व्यवहार perlsub में प्रलेखित है - यह इस करने पर निर्भर करता - perl जानता $string दायरे में है - क्योंकि my यह इतना बताता है।

मेरी ऑपरेटर वाणी सूचीबद्ध चर lexically संलग्न ब्लॉक तक ही सीमित, सशर्त (यदि/जब तक/elsif/बाकी), लूप (के लिए/foreach/जबकि/जब तक/जारी रखने के लिए), सबरूटीन, eval, या फ़ाइल/उपयोग/उपयोग की गई फ़ाइल करें।

इसका मतलब है कि यह उस बिंदु से 'गुंजाइश' है जिस पर यह 'ब्लॉक' के समापन ब्रैकेट तक पहली बार देखा गया है। (या आपके उदाहरण में - कोड का अंत)

हालांकि - आपके उदाहरण में myभी एक मान निर्दिष्ट करता है।

यह स्कोपिंग प्रक्रिया संकलन समय पर होती है - जहां पर्ल चेक करता है कि यह $string का उपयोग करने के लिए मान्य है या नहीं। (strict के लिए धन्यवाद)। हालांकि - यह नहीं पता कि मूल्य क्या था, क्योंकि कोड निष्पादन के दौरान यह बदल सकता है। (और विश्लेषण करने के लिए गैर तुच्छ है)

तो अगर आप ऐसा करते हैं यह एक छोटे से स्पष्ट हो सकता है क्या हो रहा है:

#!/usr/bin/env perl 
use strict; 
use warnings; 

my $string; #undefined 
func(); 
$string = 'string'; 
func(); 

sub func { 
    print $string, "\n"; 
} 

$string दोनों ही मामलों में दायरे में है - क्योंकि my संकलन समय पर हुआ - subroutine कहा जाने से पहले - लेकिन पहले आमंत्रण से पहले undef के डिफ़ॉल्ट से परे एक मूल्य सेट नहीं है।

नोट इस विरोधाभासों के साथ:

#!/usr/bin/env perl 
use strict; 
use warnings; 

sub func { 
    print $string, "\n"; 
} 

my $string; #undefined 
func(); 
$string = 'string'; 
func(); 

कौन सा त्रुटियों क्योंकि जब उप घोषित किया जाता है, $string नहीं दायरे में है।

4

सबसे पहले, मैं इस अपरिभाषित व्यवहार पर विचार करूंगा क्योंकि यह my को my $x if $cond; निष्पादित करता है।

उस ने कहा, व्यवहार वर्तमान में संगत और अनुमानित है। और इस उदाहरण में, यह वास्तव में व्यवहार करता है जैसा कि अपेक्षित है कि अपरिभाषित व्यवहार नोटिस से ऑप्टिमाइज़ेशन ऑप्ट आउट नहीं किया गया था।


संकलन समय में my घोषित करने और चर [1] आवंटन की प्रभाव पड़ता है। बनाए जाने पर स्केलर को अनदेखा करने के लिए प्रारंभ किया जाता है। Arrays और हैश खाली बना रहे हैं।

my $string संकलक द्वारा सामना किया गया था, इसलिए चर बनाया गया था। लेकिन चूंकि आपने अभी तक असाइनमेंट निष्पादित नहीं किया है, इसलिए पहले कॉल के दौरान func पर इसका डिफ़ॉल्ट मान (अपरिभाषित) है।

यह मॉडल बंद करके चर को पकड़ने की अनुमति देता है।

उदाहरण 1:

{ 
    my $x = "abc"; 
    sub foo { $x } # Named subs capture at compile-time. 
} 

say foo(); # abc, even though $x fell out of scope before foo was called. 

उदाहरण 2:

sub make_closure { 
    my ($x) = @_; 
    return sub { $x }; # Anon subs capture at run-time. 
} 

my $foo = make_closure("foo"); 
my $bar = make_closure("bar"); 

say $foo->(); # foo 
say $bar->(); # bar 

  1. आवंटन संभवतः टाल जाता है जब तक चर वास्तव में प्रयोग किया जाता है।
+0

मैं पालन नहीं करता हूं। चल रहा है 'perl -MDevel :: Peek -e'mysub(); मेरा $ foo; उप mysub {डंप ($ foo)} '' पैडमी ध्वज के साथ '$ foo' दिखाता है, जबकि' perl -MDevel :: Peek -e'mysub(); उप mysub {डंप ($ foo)} ''(जाहिर है) नहीं करता है। मुझे पर्लट्स के बारे में ज्यादा जानकारी नहीं है, इसलिए मैं रास्ता बंद कर सकता हूं, लेकिन ऐसा लगता है कि 'मेरा' छोड़ा नहीं जा रहा है। क्या आप और समझा सकते हैं? – ThisSuitIsBlackNot

+0

@ThisSuitIsBlackNot, यह 'मेरा' घोषित करने से पहले एक व्याख्यात्मक व्यवहार्यता का उपयोग करने के लिए अनिर्धारित व्यवहार है जो इसे घोषित करता है *। ओपी के कोड में 'func()' के पहले कॉल के बाद इसका निष्पादन आया। इसलिए, उनका कार्यक्रम अपरिभाषित व्यवहार पर निर्भर करता है। आपने केवल दिखाया है कि 'मेरे' का संकलन-समय प्रभाव है, जैसा कि मैंने कहा था। (* ये दस्तावेज़ों द्वारा उपयोग किए जाने वाले शब्द नहीं हैं। यह अस्पष्ट दस्तावेज़ों की मेरी समझ है।) – ikegami

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