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";
精彩评论