2014-02-18 46 views
0

我是Perl新手,希望對理解子程序有所幫​​助。在子例程中,是否有些變量總是未定義的?這是因爲子程序中的變量是私人的嗎?那麼如果我想要定義之前未定義的變量,我該怎麼做呢?提前致謝。Perl子程序中的未定義變量

+0

您應該查看http://perldoc.perl.org/perlintro.html它將回答您的問題,併爲使用perl進行編程提供更多幫助。 – Gabs00

回答

4

Perl中的變量不是私有的,但它們可以具有有限的範圍。例如在子例程中用my聲明它們時。子程序的參數存儲在變量@_中。

do_stuff($foo, $bar); 

sub do_stuff { 
    my ($first, $second) = @_; # direct assignment 
    print "First: $first, Second: $second\n"; 
} 

my聲明使得詞法範圍向周邊塊{ ... },這意味着它們被保護的變量,他們走出去的範圍在執行離開塊。

sub do_stuff { 
    my $first = shift; 
    my $second) = shift;  

此做同樣的事情,不同的是它也將刪除@_的元素:

參數子程序也可以用在陣列功能shiftpop,這是在Perl代碼常見訪問陣列。

瞭解更多:

1

一般來說,變量是用我的命令來定義的(技術上還有一些像我們這樣的地方,但我從來沒有使用它們)。

要定義一個變量類型:

my $variable 

如果你這樣做在子程序它會使你所需要的變量。它往往是一個好主意,用嚴格的指令在代碼:

use strict 

這會給你一些,當你忘記定義的東西警告。

+2

'my $ variable'不會「定義變量類型」。它聲明瞭一個變量。 – ikegami

2

在原材料,無怨無悔的Perl中,變量範圍全球。也就是說,它們存在於您的程序中,從您定義的位置到腳本的末尾。另外,在Perl中,當你用一個未定義的值時,變量就會出現。在字符串中,這被視爲空字符串。在數字中,它被視爲零。

因此,在一個子程序中,如果您在主程序中定義一個變量,它在你的子程序中定義:

$foo = "Hello"; 
call_sub(); 

sub call_sub { 
    print "$foo\n"; 
} 

,將打印「你好」。

但是,任何人都不應該使用Perl,在這種模式下,因爲它很容易有錯誤:

$name = "Bob" 
print "Hello $Name!\n"; 

哎呦!我在定義時使用了$name,當我使用它時使用了$Name。另外,你不需要這樣的全局變量。否則,你的子程序可能會覆蓋你的主程序變量。真的很難編寫大型複雜程序。

爲了解決這個問題,我們強烈鼓勵把這兩行代碼中的:

use strict; 
use warnings; 

use warnings;會發出各種警告,例如uninitialzed變量被視爲字符串和數字。

use strict;做出了更大的變化。簡單地說(並且不正確),use strict強制您在使用它們之前先聲明10。

use warnings; 
use strict; 

my $name = "Bob" 
print "Hello $Name\n"; 

該程序將無法正常工作,因爲$Name從未聲明(聲明與my關鍵字變量)。你可以看到如何防止錯誤。

但是,聲明這些類型的變量被稱爲詞彙範圍變量。也就是說,他們可以進出。如果在區塊中定義變量,則將在區塊以外的區域內定義一個變量。想想一個塊的花括號:

子程序是塊

sub foo { # Curly brace starts the block 
    ... 
}   # Curly brace ends the block 

這意味着,如果你在一個子程序中定義一個變量,它僅在該子程序。

此外,whilefor循環是塊:

for my $foo (@foo_list) { # The variable $foo is only defined in this loop 
    ... 
}        # End of block and end of loop 

while (my $foo = <@foo_list>) { # Again, $foo is only in this block 
    ... 
}         # End of the block 

if ($foo == $bar) {  # Another block 
    my $foo = 1;    # $foo is defined in the block 
}        # $foo is no longer defined 

你甚至可以只使用大括號:

my $foo = 1; 
print "$foo\n"    # Prints 1 
{ 
    my $foo = 2;    # Redefines $foo it's a different $foo! 
    print "$foo\n"   # Prints 2 
}        # End of block, $foo in block is now out of scope 
print "$foo\n";    # Prints 1 because the original $foo is in scope. 

讓我們在此期待:

my $foo = 2; 
my $bar = 5; 
print "$foo\n";    # Prints 2 
call_sub(5);     # Prints "Foo is 5!" 
print $foo\n";    # Prints 2 

sub call_sub { 
    my $foo = shift;   # Different $foo from main program! 
    print "Foo is $foo!\n"; 
    print "Bar is $bar\n"; # Will print "Bar is 5" because $bar is in scope 
}       # Subroutine's $foo falls out of scope 

,你可以請參閱$bar是在我調用子程序之前定義的d因此它在子例程中定義並仍在範圍內。但是,我的子程序中的$foo被重新聲明,並且一直保留到子程序結束並且超出範圍。因此,我的子程序使用$foo不會干擾我的主程序。

所以,在回答你的問題:

  • 始終使用use strict;。這將迫使你在可以使用變量之前聲明變量。
  • 變量在定義爲my前未定義。
  • 變量可以有一個有限的範圍,他們生活和呼吸。這可能非常有用。不要坐在那裏,像一樣,在程序開始時聲明所有變量,就像在Pascal中做的那樣。在他們使用的地方聲明他們,並在不需要時讓他們掉到範圍之外。
  • 子程序變量不是私人因爲子程序可以使用已經聲明的變量。這是一個壞主意,因爲它允許子程序覆蓋主程序中變量的值。所以,總是聲明所有的子程序變量my是安全的。
  • 使用use warnings;在您忘記定義您正在嘗試使用的變量時發出警告。

最後,我撒謊了,但對於一個很好的理由。 Perl中的變量比我提出的要複雜一點(很多)。你有名稱空間的概念,包變量,以及本地化變量的方法都不是本地的。即使是與Perl合作多年的人也很難理解這些後果。

use strict;並不真正強制你聲明變量。它迫使你使用你聲明的詞法作用域變量my或使用完全限定變量名對於變量(或使用our來聲明這些變量)。

但是,最後,use strict;確實會強制你聲明一個變量,因爲在Perl中將使用99%的變量將用my聲明。當你瞭解更多關於Perl的知識時,你可以更多地瞭解其他1%。

欲瞭解更多信息,看看PerlSub有關使用my私有變量,並看看PerlMod了充分討論有關包變量,使用當地,和(我怎麼能忘了!)新引入的狀態變量。