It was hoped to use the shift function on the @_ array inside a function so that the function could accept a variable number of parameters. According to p112 in "Programming Perl" by L Wall et al, the arguments passed to a subroutine are concatenated into one flat array, namely @_. It was assumed that this array could be traversed using the shift function or a foreach loop to determine say the minimum of all values passed, even if some of the arguments were themselves arrays and the values were contained as elements in those arrays.
A number of variants were tried and the min2 and min4 variants that used the "for each" loop (which is closest to that on p113 of "Programming Perl") to traverse the @_ array worked. The min1 and min3 variants which used the "shift" function to traverse the @_ array did work properly. Any ideas on what is causing the variants based on the "shift" function to fail?
The four "min" subroutines are given below:
# Using perl5.14.2.exe
use strict;
sub min {
my $m=shift @_;
my $b;
while ($b = shift @_){
if ($b < $m) {$m=$b};
};
return $m;
};
sub min_v2 {
my $m = $_[0];
foreach (@_){
if ($_ < $m) {$m = $_};
};
return $m;
};
sub min_v3 {
my $m=shift (@_);
my $b;
while ($b = shift (@_)){
if ($b < $m) {$m=$b};
};
return $m;
};
sub min_v4 {
# Similar to Programming Perl 2nd Ed by Larry Wall et al p113
my $m=shift (@_);
foreach $b (@_){
if ($b < $m) {$m=$b};
};
return $m;
};
The following code was used to test the routines:
print 'min 10,50,5,1 = ' , min (10,50,5,1 ), "\n" ;
print 'min ((10,50,5),1) = ' , min ((10,50,5),1) , "\n" ;
print 'min ((10,50,0),1) = ' , min ((10,50,0),1) , "\n" ;
print 'min (30,0) = ', min (30,0), "\n";
print 'min_v2 (30,0) = ', min_v2 (30,0), "\n";
print 'min_v3 (30,0) = ', min_v3 (30,0), "\n";
print 'min_v4 (30,0) = ', min_v4 (30,0), "\n";
my @a;
@a = (1,2,3,30);
print '@a = ' , "[ @a ]" , , "\n";
print 'min (@a,0) = ' , min (@a,0) , "\n";
print 'min_v2 (@a,0) = ' , min_v2 (@a,0) , "\n" ;
print 'min_v3 (@a,0) = ' , min_v3 (@a,0) , "\n" ;
print 'min_v4 (@a,0) = ' , min_v4 (@a,0) , "\n" ;
@a = (3,2,1,30);
print '@a = ' , "[ @a ]" , , "\n";
print 'min (@a,0) = ' , min (@a,0) , "\n";
print 'min_v2 (@a,0) = ' , min_v2 (@a,0) , "\n" ;
print 'min_v3 (@a,0) = ' , min_v3 (@a,0) , "\n" ;
print 'min_v4 (@a,0) = ' , min_v4 (@a,0) , "\n" ;
@a = (3,2,1,30);
print '@a = ' , "[ @a ]" , , "\n";
print 'min (@a,2) = ' , min (@a,2) , "\n";
print 'min_v2 (@a,2) = ' , min_v2 (@a,2) , "\n" ;
print 'min_v3 (@a,2) = ' , min_v3 (@a,2) , "\n" ;
print 'min_v4 (@a,2) = ' , min_v4 (@a,2) , "\n" ;
And the following output was generated:
min 10,50,5,1 = 1
min ((10,50,5),1) = 1
min ((10,50,0),1) = 10
min (30,0) = 30
min_v2 (30,0) = 0
min_v3 (30,0) = 30
min_v4 (30,0) = 0
@a = [ 1 2 3 30 ]
min (@a,0) = 1
min_v2 (@a,0) = 0
min_v3 (@a,0) = 1
min_v4 (@a,0) = 0
@a = [ 3 2 1 30 ]
min (@a,0) = 1
min_v2 (@a,0) = 0
min_v3 (@a,0) = 1
min_v4 (@a,0) = 0
@a = [ 3 2 1 30 ]
min (@a,2) = 1
min_v2 (@a,2) = 1
min_v3 (@a,2) = 1
min_v4 (@a,2) = 1