What does =~ do in Perl?
The variable @_
is an array (hence the @
prefix) that holds all of the parameters to the current function.
When you encounter a special (or punctuation) variable in Perl, check out the perlvar documentation. It lists them all, gives you an English equivalent, and tells you what it does.
The @_
variable is an array that contains all the parameters passed into a subroutine.
The parentheses around the $string
variable are absolutely necessary. They designate that you are assigning variables from an array. Without them, the @_
array is assigned to $string
in a scalar context, which means that $string
would be equal to the number of parameters passed into the subroutine. For example:
sub foo {
my $bar = @_;
print $bar;
}
foo('bar');
The output here is 1--definitely not what you are expecting in this case.
Alternatively, you could assign the $string
variable without using the @_
array and using the shift
function instead:
sub foo {
my $bar = shift;
print $bar;
}
Using one method over the other is quite a matter of taste. I asked this very question which you can check out if you are interested.
Perl has two different contexts, scalar context, and list context. An array '@_
', if used in scalar context returns the size of the array.
So given these two examples, the first one gives you the size of the @_
array, and the other gives you the first element.
my $string = @_ ;
my ($string) = @_ ;
Perl has three 'Default' variables $_
, @_
, and depending on who you ask %_
. Many operations will use these variables, if you don't give them a variable to work on. The only exception is there is no operation that currently will by default use %_
.
For example we have push
, pop
, shift
, and unshift
, that all will accept an array as the first parameter.
If you don't give them a parameter, they will use the 'default' variable instead. So 'shift;
' is the same as 'shift @_;
'
The way that subroutines were designed, you couldn't formally tell the compiler which values you wanted in which variables. Well it made sense to just use the 'default' array variable '@_
' to hold the arguments.
So these three subroutines are (nearly) identical.
sub myjoin{
my ( $stringl, $stringr ) = @_;
return "$stringl$stringr";
}
sub myjoin{
my $stringl = shift;
my $stringr = shift;
return "$stringl$stringr";
}
sub myjoin{
my $stringl = shift @_;
my $stringr = shift @_;
return "$stringl$stringr";
}
I think the first one is slightly faster than the other two, because you aren't modifying the @_
variable.