将'shift'分配给变量意味着什么?

时间:2011-08-16 18:03:54

标签: perl variables

示例:

use strict;
my $file = shift;

open(IN, $file) || die "Unable to open $file\n";
open(OUT, ">$file.$$") or die $!;

my $file = shift发生了什么?

4 个答案:

答案 0 :(得分:28)

如果在主程序中使用,它将shift(删除并返回)@ARGV中的第一个值,即程序的参数列表。如果在子例程中使用,它将从@_(子参数列表)中移出第一个值。有关详细信息,请参阅documentation

答案 1 :(得分:13)

您可以阅读shift上的文档。很清楚。 shift接受一个数组并提取第一个元素(实际上将其从数组中删除)。如果您不提供任何数组,它将使用@ARGV(程序命令行的参数)来读取数据。如果你在函数内,它使用@_,即函数的参数。

示例:

my @array = (1, 2, 3);
my $value = shift @array;
print $value; # will print '1'

答案 2 :(得分:5)

shift使用@_变量,其中包含传递给函数的值,shift使用@ARGV传递给脚本本身的值shift在函数之外引用。

一个小心的注意事项:这可能是明智的,特别是在许多路径包含空格的Windows中,当您将文件名和路径传递给脚本或函数时,将文件名和路径放在单引号中。这将告诉Perl您传递的是单个标量值而不是值数组。如果要插入部分名称,可以使用双引号。例如:

my $path = 'C:\Goat Kids';
func("$path\\goat.txt");

或者,如果要将文件名直接传递给脚本,请从命令行:

perl goat.pl "C:\Goat Kids\goat.txt"

答案 3 :(得分:2)

之前的答案描述了shift的工作原理。我想评论为什么在你自己的程序中使用它是个好主意。

默认情况下,Perl是一种传递引用语言。如果子例程修改了其参数,则调用者将看到这些(有时是意外的)更改。使用shift将子例程参数分配给私有变量是一种很好的做法。这样,如果对其进行任何更改,调用者将无法看到它。例如,下面的代码输出

1
2
2

第一个子例程修改其参数,调用者看到更改。第二个子例程修改其参数的私有副本,并且此更改在调用者中不可见。

use strict;
use warnings;

sub pass_by_ref {
    $_[0] = 2;
}

sub pass_by_value {
    my $x = shift @_;
    $x = 3;
}

my $x = 1;
print $x, "\n";
pass_by_ref($x);
print $x, "\n";
pass_by_value($x);
print $x, "\n";