简体   繁体   English

对于我是否将标量或数组传递给perl中的子例程感到困惑?

[英]Confused about whether I'm passing a scalar or an array to a subroutine in perl?

I've just started learning perl and I am am confused by this exercise (from Learning Perl Chapter 4). 我刚刚开始学习perl,我对此练习感到困惑(来自Learning Perl第4章)。

At the beginning of the greet() subroutine, I am trying to assign the argument $_ to my $name (my $name = $_) variable but it doesn't work. 在greet()子例程的开头,我试图将参数$ _分配给我的$ name(我的$ name = $ _)变量,但它不起作用。 The book says to use "my name = shift;" 这本书说要用“我的名字=班次”; but I don't understand why . 但我不明白为什么 shift is used to remove a value from an array and my argument is not an array as far as I can tell, it's a string inside a scalar! shift用于从数组中删除一个值,据我所知,我的参数不是一个数组,它是一个标量内的字符串!

Could anyone explain what I'm not understanding? 谁能解释一下我不理解的东西?

Thanks! 谢谢! Here is the entirety of the code. 这是整个代码。

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' );

In chapter 4 of Learning Perl (6th edition) there's a section called Arguments . 在Learning Perl(第6版)的第4章中,有一个名为Arguments的部分。 There it states the following: 在那里它陈述如下:

This means that the first subroutine parameter is in $_[0] , the second one is stored in $_[1] , and so on. 这意味着第一个子例程参数在$_[0] ,第二个子例程存储在$_[1] ,依此类推。 But - and here's an important note - these variables have nothing whatsoever to do with the $_ variable, any more than $dino[3] (an element of the @dino array) has to do with $dino (a completely distinct scalar variable). 但是-这里是一个重要的注意事项-这些变量都毫无关系与$_变量,任何超过$dino[3]的元素@dino阵列)具有做$dino (一个完全不同的标量变量)。 It's just that the parameter list must be in some array variable for your subroutine to use it, and Perl uses the @_ for this purpose. 只是参数列表必须在某个数组变量中才能使子程序使用它,而Perl为此目的使用@_

( Learning Perl, 6th Edition, Chapter 4 ) 学习Perl,第6版,第4章

So you're probably mistaken in using $_ , when you should either be using my $name = $_[0]; 所以当你应该使用my $name = $_[0];时,你可能会错误地使用$_ my $name = $_[0]; , or my $name = shift @_; ,或my $name = shift @_; . As a convenience, when you're inside of a subroutine, shift defaults to shifting off of @_ if you provide no explicit argument, so the common idiom is to say my $name = shift; 为方便起见,当你是一个子程序内, shift默认为关闭的换挡@_如果您提供没有明确的说法,所以常见的成语是说my $name = shift; .

For those in need of another resource, perldoc perlintro also has a good (and appropriately brief) explanation of passing parameters to subroutines and accessing them via @_ or shift . 对于那些需要其他资源的人来说, perldoc perlintro对于将参数传递给子程序并通过@_shift访问它们也有一个很好的(并且适当简要)解释。

Here's a brief snippet from perlintro : 以下是perlintro的简短片段:

What's that shift ? 那是什么shift Well, the arguments to a subroutine are available to us as a special array called @_ (see perlvar for more on that). 好吧,子程序的参数可以作为一个名为@_的特殊数组使用(有关详细信息,请参阅perlvar )。 The default argument to the shift function just happens to be @_ . shift函数的默认参数恰好是@_ So my $logmessage = shift; 所以my $logmessage = shift; shifts the first item off the list of arguments and assigns it to $logmessage . 将第一项移出参数列表并将其分配给$logmessage

It sounds like you have skipped part of the chapter. 听起来你已经跳过了章节的一部分。 Did you read the section on Arguments (on page 66 in the latest, sixth edition). 您是否阅读了关于参数的部分(最新的第六版第66页)。 It says 它说

Perl passes the list to the subroutine; Perl将列表传递给子例程; that is, Perl makes the list available for the subroutine to use however it needs to. 也就是说,Perl使列表可用于子程序,但需要使用。 Of course, you have to store this list somewhere, so Perl automatically stores the parameter list (another name for the argument list) in the special array variable named @_ for the duration of the subroutine. 当然,您必须将此列表存储在某处,因此Perl会在子例程的持续时间内自动将参数列表(参数列表的另一个名称)存储在名为@_的特殊数组变量中。 You can access this array to determine both the number of arguments and the value of those arguments. 您可以访问此数组以确定参数的数量和这些参数的值。

This means that the first subroutine parameter is in $_[0], the second one is stored in $_[1], and so on. 这意味着第一个子例程参数在$ _ [0]中,第二个子例程存储在$ _ [1]中,依此类推。 But—and here's an important note—these variables have nothing whatsoever to do with the $_ variable, any more than $dino[3] (an element of the @dino array) has to do with $dino (a completely distinct scalar variable). 但是 - 这里有一个重要的注意事项 - 这些变量与$ _变量没有任何关系,任何超过$ dino [3](@dino数组的一个元素)都与$ dino(一个完全不同的标量变量)有关)。 It's just that the parameter list must be in some array variable for your subroutine to use it, and Perl uses the array @_ for this purpose. 只是参数列表必须在子程序的某个数组变量中才能使用它,而Perl为此目的使用数组@_。

The arguments of all perl subroutines live inside an array of parameters, which your book fails to mention. 所有perl子例程的参数都存在于一个参数数组中,您的书无法提及。

This array is @_ , and in your case by shift you shall get your first argument, which will be a scalar. 这个数组@_ ,并在你的情况下,通过shift你将得到你的第一个参数,这将是一个标量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM