4

我刚刚开始学习 perl,我对这个练习感到困惑(来自学习 Perl 第 4 章)。

在 greet() 子例程的开头,我试图将参数 $_ 分配给我的 $name (my $name = $_) 变量,但它不起作用。这本书说要使用“我的名字=班次;” 但我不明白为什么。shift 用于从数组中删除一个值,据我所知,我的参数不是数组,它是标量内的字符串!

谁能解释我不明白的地方?

谢谢!这是整个代码。

use 5.012;
use warnings;
use utf8;

sub greet {
   my $name = $_;
   state $last_person ;
   if (defined $last_person ) {
          print "Hi $name! $last_person is also here!\n";

   } else {
          print "Hi $name! You are the first one here!\n";
   }
   $last_person = $name;
}

greet( 'Fred' );
greet( 'Barney' );
greet( 'Wilma' );
greet( 'Betty' );
4

3 回答 3

8

在 Learning Perl(第 6 版)的第 4 章中,有一节称为Arguments。在那里它陈述了以下内容:

这意味着第一个子程序参数在 中$_[0],第二个参数存储在 中$_[1],依此类推。$_但是 - 这里有一个重要说明 - 这些变量与变量没有任何关系,就像 $dino[3](数组的元素@dino )与$dino(完全不同的标量变量)有任何关系。只是参数列表必须在某个数组变量中才能让您的子例程使用它,而 Perl 就是@_为此目的使用 。

学习 Perl,第 6 版,第 4 章

$_因此,当您应该使用my $name = $_[0];或时,您可能会误用my $name = shift @_;. 为方便起见,当您在子例程中shift时,如果您未提供显式参数,则默认为关闭@_,因此常见的习惯用法是my $name = shift;.

对于那些需要其他资源的人,perldoc perlintro也有一个很好的(并且适当简短的)解释将参数传递给子例程并通过@_or访问它们shift

这是一个简短的片段perlintro

那是什么shift?好吧,子例程的参数可以作为一个特殊的数组提供给我们@_perlvar有关详细信息,请参阅)。该shift函数的默认参数恰好是@_. 因此my $logmessage = shift;将第一项从参数列表中移出并将其分配给$logmessage.

于 2012-07-07T21:23:08.523 回答
4

听起来你已经跳过了本章的一部分。你读过论据部分吗(最新第六版的第 66 页)。它说

Perl 将列表传递给子程序;也就是说,Perl 使列表可供子例程根据需要使用。当然,您必须将这个列表存储在某个地方,因此 Perl 在子例程期间自动将参数列表(参数列表的另一个名称)存储在名为 @_ 的特殊数组变量中。您可以访问此数组以确定参数的数量和这些参数的值。

这意味着第一个子程序参数在 $_[0] 中,第二个参数存储在 $_[1] 中,依此类推。但是——这里有一个重要的说明——这些变量与 $_ 变量没有任何关系,就像 $dino[3](@dino 数组的一个元素)与 $dino(一个完全不同的标量变量)有任何关系。 )。只是参数列表必须在某个数组变量中才能让您的子例程使用它,而 Perl 使用数组 @_ 来达到此目的。

于 2012-07-07T21:26:04.240 回答
2

所有 perl 子例程的参数都存在于一个参数数组中,你的书没有提到。

这个数组是@_,在你的情况下,shift你将得到你的第一个参数,这将是一个标量。

于 2012-07-07T21:03:55.257 回答