Subroutines in Perl

walden systems, geeks corner, developer, perl, code, authentication, active directory, array, split, join, slice, elements, scalar, subroutines, parameters, lists, arrays, hashes
Perl 5 is a highly capable, feature-rich programming language with over 30 years of development. Perl 5 runs on over 100 platforms from portables to mainframes and is suitable for both rapid prototyping and large scale development projects.

Perl allows us to define our own functions, in Perl, we call them subroutines. They are used for code reusability, so we don't have to write the same code over again. For example if we want to take input from user in several places of our program, then we can write the code in a subroutine and call the subroutine wherever we want to take input. This way, we do not have to write the same code again, this also improves code readability.

Defining and calling a subroutine

The first thing we need to do to create a subroutine is to define the subroutine using the sub keyword. Unlike PHP, we don't need to have parenthesis to pass parameters. Before Perl 5.0, we had to use an & to call a subroutine but from 5.0 on, we call the subroutine with just the subroutine name and a list of arguments in parenthesis.

Defining a subroutine

 
1    sub mySub
2    {
3        print "Hello World" ;
4    }
5
6    mySub() ;
7    &mySub() ;

Line 6 is for Perl version 5.0 and later. Line 7 was the old way to call subroutines. The & still works but isn't recommended since it bypasses the subroutine prototypes.


Passing parameters to subroutines

In the example above, we are not passing any parameters but we can pass parameters when calling a subroutine. Perl stores all parameters in special array denoted by @_. So the first argument to the function is in $_[0], the second is in $_[1], and so on. We can pass arrays and hashes as arguments like any scalar but passing more than one array or hash can cause them to lose their separate identities. So we will need use references to pass any array or hash.

1    sub mySub1 
2    {
3       printf "@_";
4       return;
5    }
6
7    sub mySub2
8    {
9       printf "_[0], _[1]";
10      return;
11   }
12
13   mySub1("This", "is", "my", "subroutine");
14   mySub2("This", "is", "my", "subroutine");

The output of line 13 is : This is my subroutine. The output of line 14 is This, is.

Passing lists and hashes to a subroutine

Since the @_ variable is an array, it can be used to supply lists to a subroutine. However, because of the way in which Perl receives and parses lists and arrays, it can be difficult to extract the individual elements from @_. If you have to pass a list along with other scalar arguments, then make list as the last argument. When you supply a hash to a subroutine or operator that accepts a list, then hash is automatically translated into a list of key/value pairs. Perl makes it easier to send an unknown number of parameters to a subroutine compared to Python since all parameters are sent in as a single array. In, Python, we would use the *args to pass an unknown number of arguments.

1    sub PrintList 
2    {
3        my @list = @_;
4        print "Given list is @list
";
5    }
6
7    sub PrintHash 
8    {
9        my (%hash) = @_;
10
11       foreach my $key ( keys %hash ) 
12       {
13           my $value = $hash{$key};
14           print "$key : $value ";
15       }
16   }
17
18   $a = 0;
19   @b = (1, 2, 3, 4);
20   PrintList($a, @b);
21
22   %hash = ('name' => 'John', 'age' => 18);
23   PrintHash(%hash);


Line 20 will output 0 1 2 3 4 5. Line 23 will output name : John age : 18.

Returning values

We can return a value from subroutine like we can in any other programming language. If are not returning a value from a subroutine then whatever calculation is last performed in a subroutine is automatically also the return value. We can return arrays and hashes from the subroutine like any scalar but returning more than one array or hash normally causes them to lose their separate identities. So we will need to use references to return any array or hash from a function.

sub Addnum 
{
    foreach $item (@_) 
    {
       $sum += $item;
    }

    return $sum;
}

$num = Average(10, 20, 30);
print "$num
";
Will output 60