shift
?檢索子例程的參數(shù)子例程的參數(shù)來自于特殊的?@_
?數(shù)組。不帶參數(shù)的?shift
?默認(rèn)使用?@_
。
sub volume {
my $height = shift;
my $width = shift;
my $depth = shift;
return $height * $width * $depth;
}
你也可以使用列表賦值賦給子例程參數(shù):
sub volume {
my ($height, $width, $depth) = @_;
return $height * $width * $depth;
}
@_
?直接處理子例程參數(shù)在某些情況下,但我們希望很少,你能夠通過?@_
?數(shù)組直接訪問參數(shù)。
sub volume {
return $_[0] * $_[1] * $_[2];
}
傳遞給子例程的參數(shù)是實(shí)際參數(shù)的別名。
my $foo = 3;
print incr1($foo) . "\n"; # prints 4
print "$foo\n"; # prints 3
sub incr1 {
return $_[0]+1;
}
如果你想要這種效果的話,這樣更好:
sub incr2 {
return ++$_[0];
}
如果你喜歡,你能夠?qū)⑷我鈻|東傳遞給子例程。
sub square {
my $number = shift;
return $number * $number;
}
my $n = square( 'Dog food', 14.5, 'Blah blah blah' );
該函數(shù)只會(huì)使用第一個(gè)參數(shù)。因?yàn)檫@個(gè)關(guān)系,你可以使用任意數(shù)目的參數(shù), 甚至沒有參數(shù)來調(diào)用函數(shù)。
my $n = square();
Perl 不會(huì)對(duì)此抱怨。
Params::Validate?模塊解決了許多驗(yàn)證問題。
在演進(jìn)的道路上加入了原型,因此你可以像這樣干:
sub square($) {
...
}
my $n = square( 1, 2, 3 ); # run-time error
無論如何都不要使用它們。它們不會(huì)作用于對(duì)象,它們需要在調(diào)用子例程 前先予以聲明。它們是好想法,但只是不實(shí)用。
BEGIN
?塊在編譯時(shí)做事BEGIN
?是一種特殊的代碼塊類型。它允許程序員在 Perl 的編譯階段執(zhí)行 代碼,這樣可以執(zhí)行初始化及做其他事情。
Perl 使用?BEGIN
?在任意時(shí)導(dǎo)入模塊。下列兩個(gè)語句是等效的:
use WWW::Mechanize;
BEGIN {
require WWW::Mechanize;
import WWW::Mechanize;
}
記住傳給子例程的參數(shù)是作為一個(gè)大數(shù)組傳遞的。如果你像下面這樣干:
my @stooges = qw( Moe Larry Curly );
my @sandwiches = qw( tuna ham-n-cheese PBJ );
lunch( @stooges, @sandwiches );
那么傳給?lunch
?的是列表:
( "Moe", "Larry", "Curly", "tuna", "ham-n-cheese", "PBJ" );
在?lunch
?中,你如何能告訴 stooges 結(jié)束及 sandwiches 開始的位置? 你不能。如果你嘗試這樣:
sub lunch {
my (@stooges, @sandwiches) = @_;
那么所有 6 個(gè)元素都會(huì)跑到?@stooges
?中,而?@sandwiches
?什么都不會(huì) 得到。
答案是使用引用,正如:
lunch( \@stooges, \@sandwiches );
sub lunch {
my $stoogeref = shift;
my $sandwichref = shift;
my @stooges = @{$stoogeref};
my @sandwichref = @{$sandwichref};
...
}
更多建議: