开发者

What does assigning 'shift' to a variable mean?

Example:

use strict;开发者_Python百科
my $file = shift;

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

What is going on with the my $file = shift?


If used in the main program, it will shift (remove and return) the first value from @ARGV, the argument list of your program. If used inside a subroutine, it will shift the first value from @_, the argument list of the sub. See the documentation for more info.


You can read the documentation on shift. It is very clear. shift accepts an array and extracts the first element (actually removing it from the array). If you don't provide any array, it uses @ARGV (the arguments to the command line of the program) to read the data. If you're inside a function, it uses @_, namely, the parameters of the function.

Example:

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


shift uses the @_ variable which contains the values passed to a function or shift uses @ARGV for the values passed to the script itself if shift is referenced outside of a function.

ONE WORD OF CAUTION: It is probably wise, especially in Windows where many paths contain spaces, to put the filename and path in single quotes when you pass it to the script or function. This will tell Perl that you are passing it a single scalar value rather than an array of values. You can use double quotes if you want to interpolate part of the name. For example:

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

Or, from the command line if you are passing the filename directly to the script:

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


The previous answers have described how shift works. I would like to comment on why it is a good idea to use it in your own programs.

Perl by default is a pass-by-reference language. If a subroutine modifies its argument, the caller will see these, sometimes unexpected, changes. It is a good practice to use shift to assign a subroutine argument to a private variable. This way, if you make any changes to it, it will not be visible to the caller. E.g., the code below outputs

1
2
2

The first subroutine modifies its argument and the caller sees the change. The second subroutine modifies a private copy of its argument, and this change is not visible in the caller.

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";
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜