子例程的参数来自于特殊的 数组。不带参数的 shift 默认使用 @

    使用列表赋值来赋给子例程参数

    你也可以使用列表赋值赋给子例程参数:

    1. sub volume {
    2. my ($height, $width, $depth) = @_;
    3. return $height * $width * $depth;
    4. }

    在某些情况下,但我们希望很少,你能够通过 @_ 数组直接访问参数。

    1. return $_[0] * $_[1] * $_[2];
    2. }

    传递的参数能被修改

    传递给子例程的参数是实际参数的别名。

    1. my $foo = 3;
    2. print incr1($foo) . "\n"; # prints 4
    3. print "$foo\n"; # prints 3
    4. sub incr1 {
    5. return $_[0]+1;
    6. }

    如果你想要这种效果的话,这样更好:

    1. sub square {
    2. my $number = shift;
    3. return $number * $number;
    4. my $n = square( 'Dog food', 14.5, 'Blah blah blah' );

    该函数只会使用第一个参数。因为这个关系,你可以使用任意数目的参数,甚至没有参数来调用函数。

    1. my $n = square();

    Perl 不会对此抱怨。

    Params::Validate 模块解决了许多验证问题。

    Perl 有原型,忽略它们

    在演进的道路上加入了原型,因此你可以像这样干:

    1. sub square($) {
    2. ...
    3. }
    4. my $n = square( 1, 2, 3 ); # run-time error

    无论如何都不要使用它们。它们不会作用于对象,它们需要在调用子例程前先予以声明。它们是好想法,但只是不实用。

    Perl 使用 BEGIN 在任意时导入模块。下列两个语句是等效的:

    传递数组及哈希引用

    记住传给子例程的参数是作为一个大数组传递的。如果你像下面这样干:

    1. my @stooges = qw( Moe Larry Curly );
    2. my @sandwiches = qw( tuna ham-n-cheese PBJ );
    3. lunch( @stooges, @sandwiches );

    那么传给 lunch 的是列表:

    1. ( "Moe", "Larry", "Curly", "tuna", "ham-n-cheese", "PBJ" );

    lunch 中,你如何能告诉 stooges 结束及 sandwiches 开始的位置?你不能。如果你尝试这样:

    1. my (@stooges, @sandwiches) = @_;

    那么所有 6 个元素都会跑到 @stooges 中,而 @sandwiches 什么都不会得到。