Wednesday, December 19, 2012

Perl - Return a value from function depending on the context



 How to return a value from a function depending on the context? For example, if the return value is collected into an array, the function should return an array, if collected in a scalar, then the return value should be a specific scalar. Let us see how to handle this situation in Perl.

  The Perl script below uses a function "calc" which for a given array as input, calculates the sum of all elements in the array, and also finds the biggest and smallest  number in the array.

Before:
#!/usr/bin/perl

use warnings;
use strict;
use List::Util qw(sum max min);

$\="\n";

sub calc {
        my @arr=@_;
        my @result;
        @result=(sum(@arr),max(@arr),min(@arr));
        return @result;
}

my @num=(10,18,14);

#Calling the function in list context
my ($sum,$max,$min)=calc(@num);
print "The results are : $sum, $max, $min ";

#Calling the function in scalar context:
$sum=calc(@num);
print "The sum is : $sum ";
Results on running this Perl script:
The results are : 42, 18, 10
The sum is : 3
  The second line of output is perplexing!!! 3 is not desired. When the return value of function "calc" is taken in an array, the desired results are obtained. However, when the return value is collected in scalar, 3 is obtained instead of the sum. This happened because an array in scalar context gives the length of the array which is 3 in this case.

So, how to change the above program so that when the collecting variable is array, all the 3 results should be present, else if it scalar, only sum should be returned? The answer is: wantarray.

After:
#!/usr/bin/perl

use warnings;
use strict;
use List::Util qw(sum max min);

$\="\n";

sub calc {
        my @arr=@_;
        my @result;
        @result=(sum(@arr),max(@arr),min(@arr));
        wantarray? @arr : $arr[0];
}

my @num=(10,18,14);
my ($sum,$max,$min)=calc(@num);
print "The results are : $sum, $max, $min ";

$sum=calc(@num);
print "The sum is : $sum ";
Results on running the above script:
The results are : 42, 18, 10
The sum is : 42
   The sum obtained now is 42. wantarray is a Perl built-in function which returns true if the context of the current subroutine is expecting a list value, else returns false. Hence, using the wantarray function, the entire array is returned if true, else only the 1st value, which is the sum, is returned.

Example of wantarray in CPAN:  An example of wantarray is the fileparse function is File::Basename. The fileparse function depending on the context either returns only the filename or filename, path and suffix as well.

No comments:

Post a Comment