2011-06-21 12 views
9

निम्नलिखित कोड क्यों चेतावनी देता है? $ मैच को ब्लॉक के दौरान स्कॉप्ड किया गया है और ब्लॉक के दौरान युक्त नहीं है।मुझे if/elsif पेड़ में एक ही स्कोप चेतावनी में डुप्लिकेट घोषणा क्यों मिलती है?

use strict; 
use warnings; 
use 5.012; 

use IO::All; 

my $file = io($ARGV[0])->tie; 
my $regex = qr//; 

while (my $line = <$file>) { 
    if (my ($match) = $line =~ $regex) { 
    ... 
    } 
    elsif (my ($match) = $line =~ $regex) { 
    ... 
    } 
    say $match; 
} 

C:\>perl testwarn.pl test.log 
"my" variable $match masks earlier declaration in same scope at testwarn.pl line 15. 
Global symbol "$match" requires explicit package name at testwarn.pl line 18. 
Execution of testwarn.pl aborted due to compilation errors. 

जैसी उम्मीद थी, यह शिकायत है कि $ मैच लाइन 18 पर परिभाषित नहीं है, लेकिन यह भी अगर ब्लॉकों में $ मैच की पुन: घोषणा के बारे में शिकायत। संस्करण थोड़ा पुराना है लेकिन बहुत गंभीर नहीं है; और यह हाल ही में स्ट्राबेरी संस्करण है:

This is perl 5, version 12, subversion 3 (v5.12.3) built for MSWin32-x86-multi-thread 
+0

ब्लॉक से पहले आप अपने $ मिलान चर को परिभाषित क्यों नहीं कर सकते? –

+0

क्योंकि मैं चाहता हूं कि यह ब्लॉक के लिए स्कॉप्ड हो, न कि ब्लॉक के लिए। यह एक साथ शिकायत कर रहा है कि मैं इसे (अगर) में फिर से परिभाषित कर रहा हूं जो बताता है कि यह समय {} ब्लॉक को परिभाषित किया गया है; जबकि मैं शिकायत करता हूं कि अगर मैं इसे बाद में ब्लॉक में उपयोग करने का प्रयास करता हूं। बस यह सुनिश्चित करने की कोशिश कर रहा हूं कि मैं आंतरिक रूप से आंतरिक समझता हूं। – Oesor

उत्तर

14

पहले $match घोषणा की गुंजाइश पूरे if-elsif-else ब्लॉक है। यही कारण है कि आप इस तरह की बातें करने देता है:

if ((my $foo = some_value()) < some_other_value()) { 
    do_something(); 
} elsif ($foo < yet_another_value()) { # same $foo as in the if() above 
    do_something_else(); 
} else { 
    warn "\$foo was $foo\n"; # same $foo 
} # now $foo goes out of scope 
print $foo; # error under 'use strict' => $foo is now out of scope 

हम इस ब्लॉक में कहीं और my $foo घोषित करने के लिए, elsif (...) खंड में भी शामिल थे, तो है कि एक ही दायरे में एक नकली घोषणा होगा, और हम एक मिल चाहते हैं चेतावनी संदेश।

+0

इससे थोड़ा अधिक समझ आता है। धन्यवाद! – Oesor

+2

बिल्कुल नहीं: 'अगर (मेरा $ foo) {my $ foo}' चेतावनी नहीं देता है। 'if' दो scopes बनाता है: एक पूरे कथन (शर्तों सहित) और प्रत्येक शरीर ब्लॉक के लिए एक। दूसरा दायरा पहले का बच्चा है, इसलिए "फिर" ब्लॉक स्थिति में घोषित चर देख सकता है। – ikegami

1

इस ब्लॉक

if (my ($match) = $line =~ $regex) { 
... 
elsif (my ($match) = $line =~ $regex) { 

स्कोप अगर/किसी और ब्लॉक करने के लिए $match और जब तक पाश के लिए नहीं। और फिर भी आप इसे ब्लॉक ब्लॉक से संदर्भित कर रहे हैं।

चाल इसे यहाँ

my $match; 
if ($match = ($line =~ $regex)) { 
+0

यदि यह शिकायतकर्ता ब्लॉक के लिए है, तो यह क्यों मरता है "ग्लोबल प्रतीक" $ मैच "testwarn.pl लाइन 18 पर स्पष्ट पैकेज नाम की आवश्यकता है।" जब मैं इसे संलग्न ब्लॉक में एक्सेस करने का प्रयास करता हूं? इसमें एक या दूसरे के साथ समस्या होनी चाहिए, लेकिन दोनों नहीं। – Oesor

+0

हाँ, गूंगा कॉपी पेस्ट गलती – zellio

-2

यह चेतावनी

no warnings qw/misc/; 
युक्त ब्लॉक में

सहित द्वारा दबा दिया जा सकता है। ऐसा करने पर, यह पुनर्विक्रय के बारे में चेतावनी नहीं देगा लेकिन यदि ब्लॉक के बाहर चर का उपयोग करने का प्रयास करते समय भी मर जाएगा।

+0

चेतावनियां बंद करना क्या हो रहा है यह समझने के लिए एक गरीब विकल्प है। और जब आप एक ही दायरे में एक चर को मुखौटा करते हैं तो यह मर नहीं जाता है, यह केवल चेतावनी देता है। –

+0

if-elsif-else कथन के बाहर $ match का उपयोग करने का प्रयास करते समय मर जाता है। और अगर मैं आपसे सहमत नहीं था: चेतावनियां बंद करना मैंने यहां पहली बार प्रश्न पोस्ट नहीं किया होता। – Oesor

+0

त्रुटि छिपाना हालांकि इष्टतम समाधान नहीं है। – TLP

4

क्योंकि एक चर एक if परीक्षा में घोषित पूरे if/elsif/else बयान को दिखाई देती है:

#!/usr/bin/perl 

use strict; 
use warnings; 

sub test { 
    if (my $arg = shift) { 
     print "$arg is true\n"; 
    } else { 
     print defined $arg ? $arg : "undef", " is false\n"; 
    } 
} 

test undef; 
test 0; 
test 0.0; 
test "0.0"; 
test 1 
1

if पूरे बयान के लिए एक शाब्दिक गुंजाइश बनाता है, और प्रत्येक ब्लॉक के लिए एक और शाब्दिक गुंजाइश (curlies)।

A 
if (B) { 
    C 
} elsif (B) { 
    D 
} else { 
    E 
} 
A 

« "मेरे" चर% s मास्क पहले घोषणा में एक ही शाब्दिक गुंजाइश परिणामों में ही नाम के दो चर को परिभाषित करना:

निम्नलिखित में, प्रत्येक अक्षर एक शाब्दिक गुंजाइश की अवधि का प्रतिनिधित्व करता है उसी क्षेत्र में » चेतावनी।

0xवैश्विक प्रतीक "% s" में एक वर्णक्रमीय दायरे या पूर्वजों के लिक्सिकल स्कोप परिणामों में घोषित एक चर का उपयोग करने के लिए स्पष्ट पैकेज नाम » त्रुटि की आवश्यकता है।

  • लेक्सिकल स्कॉप्स "सी", "डी" और "ई" शब्दावली के दायरे "बी" के बच्चे हैं।
  • लेक्सिकल स्कोप "बी" व्याख्यात्मक दायरे "ए" का एक बच्चा है।
संबंधित मुद्दे

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