I am new to Perl, can anyone explain the following scripts for me please:
#!/usr/bin/env perl
use strict;
use warnings;
sub f1($) { my ($v) = @_; print "f1 $v\n"; }
sub f2(@) { my ($v) = @_; print "f2 $v\n"; }
my $s = "ww";
my @a = ("xx", "yy", "zz");
f1 $s; f1 @a; f2 $s; f2 @a;
The output in my computer is :
f1 ww
f1 3
f2 ww
f2 xx # why!!
Can anyone explain why the fourth output is xx? I thought it should be zz, since when array converts to scalar, it should be the last element of array.
No, with a statement such as:
$vwill be assigned the first value in the@_array,$foothe second, and so on. This is because the parentheses impose a list context. Any excess values will be ignored, unless one of your variables is an array, in which case it will slurp all remaining values.$vwill get the first value,@fooall the rest.$barwill be undefined.You may be thinking of assignment using a list:
But this is wrong, and will cause an error:
This is because the LHS using scalar context, it will (more or less) be similar to:
You may notice that if we impose list context by putting
$vinside parentheses, we get a different result:ETA: Regarding prototypes:
In
f1, what you see is that the array is forced into scalar context because the subroutine expects a scalar argument. That is whyf1with an array prints3(the size). When the prototype looks for an array, the array remains in default list context, and the assignment is done as per normal (as described above).As an extra note: prototypes have a very specific use, to make subroutines behave more like certain built-ins with regard to argument handling. Such as
sort { code here }orpush @array, $foo.If this is not what you are after, you should skip prototypes all together and simply write:
Documentation here