Easy Tutorial
❮ Perl Formats Perl Intro ❯

Perl Subroutines (Functions)

Perl subroutines are user-defined functions.

A Perl subroutine is a separate block of code that performs a specific task, making it easier to reduce repetitive code and improve program readability.

Perl subroutines can appear anywhere in the program, with the following syntax:

sub subroutine {
   statements;
}

The syntax for calling a subroutine is:

subroutine(argument list);

In versions of Perl below 5.0, subroutines are called as follows:

&subroutine(argument list);

Although this method is still supported in newer versions, it is not recommended.

Next, let's look at a simple example:

Example

#!/usr/bin/perl

# Function definition
sub Hello {
   print "Hello, World!\n";
}

# Function call
Hello();

Executing the above program will output:

Hello, World!

Passing Parameters to Subroutines

Perl subroutines can accept multiple parameters, similar to other programming languages. The subroutine parameters are indicated by the special array @_.

Thus, the first parameter is $_[0], the second parameter is $_[1], and so on.

Regardless of whether the parameters are scalar or array types, when passing parameters to a subroutine, Perl defaults to calling them by reference.

Example

#!/usr/bin/perl

# Define average function
sub Average {
   # Get all passed parameters
   $n = scalar(@_);
   $sum = 0;

   foreach $item (@_) {
      $sum += $item;
   }
   $average = $sum / $n;
   print "Passed parameters are: @_\n";         # Print the entire array
   print "First parameter value is: $_[0]\n";    # Print the first parameter
   print "Average of passed parameters is: $average\n";  # Print the average
}

# Call the function
Average(10, 20, 30);

Executing the above program will output:

Passed parameters are: 10 20 30
First parameter value is: 10
Average of passed parameters is: 20

Users can change the values in the @_ array to modify the corresponding actual parameters.

Passing Lists to Subroutines

Since the @_ variable is an array, it can pass lists to subroutines.

However, if we need to pass both scalar and array parameters, we need to place the list as the last parameter, as shown below:

Example

#!/usr/bin/perl

# Define function
sub PrintList {
   my @list = @_;
   print "List is: @list\n";
}
$a = 10;
@b = (1, 2, 3, 4);

# List parameter
PrintList($a, @b);

The above program combines a scalar and an array, and the output is:

List is: 10 1 2 3 4

We can pass multiple arrays and hashes to a subroutine, but this can cause loss of independent identity. Therefore, we need to use references (discussed in the next section) to pass them.

Passing Hashes to Subroutines

When passing a hash table to a subroutine, it is copied into @_, and the hash table is expanded into a list of key/value pairs.

Example

#!/usr/bin/perl

# Method definition
sub PrintHash {
   my (%hash) = @_;

   foreach my $key (keys %hash) {
      my $value = $hash{$key};
      print "$key : $value\n";
   }
}
%hash = ('name' => 'tutorialpro', 'age' => 3);

# Pass hash
PrintHash(%hash);

Executing the above program will output:

age : 3
name : tutorialpro

Subroutine Return Values

Subroutines can return function values using the return statement, similar to other programming languages.

If the return statement is not used, the last statement in the subroutine will be treated as the return value.

Example

#!/usr/bin/perl

# Method definition
sub add_a_b {
   # Without using return
   $_[0] + $_[1];

   # Using return
   # return $_[0] + $_[1];
}
print add_a_b(1, 2);

Executing the above program will output:

3

In subroutines, we can return scalars, arrays, and hashes, but returning multiple arrays and hashes can cause loss of independent identity. Therefore, we need to use references (discussed in the next section) to return multiple arrays and functions.


Private Variables in Subroutines

By default, all variables in Perl are global, meaning they can be called anywhere in the program.

If we need to set private variables, we can use the my operator. The my operator is used to create lexically scoped variables. Variables created with my exist from the point of declaration until the end of the enclosing scope.

The enclosing scope can be defined by a pair of braces, a file, or constructs like if, while, for, foreach, eval strings.

The following example demonstrates how to declare one or more private variables:

sub somefunc {
   my $variable; # $variable is not visible outside of somefunc()
   my ($another, @an_array, %a_hash); # Declaring multiple variables at once
}

Example

#!/usr/bin/perl

# Global variable
$string = "Hello, World!";

# Function definition
sub PrintHello {
   # Private variable for PrintHello function
   my $string;
   $string = "Hello, tutorialpro!";
   print "String inside function: $string\n";
}
# Calling the function
PrintHello();
print "String outside function: $string\n";

The output of the above program is:

String inside function: Hello, tutorialpro!
String outside function: Hello, World!

Temporary Assignment of Variables

We can use local to provide temporary values to global variables, which revert to their original values upon exiting the scope.

Variables defined with local do not exist in the main program but do exist in the subroutine and any subroutines it calls. They can be assigned values upon definition, like so:

Example

#!/usr/bin/perl

# Global variable
$string = "Hello, World!";

sub Printtutorialpro {
   # Private variable for PrintHello function
   local $string;
   $string = "Hello, tutorialpro!";
   # Subroutine called by Printtutorialpro
   PrintMe();
   print "String value inside Printtutorialpro function: $string\n";
}
sub PrintMe {
   print "String value inside PrintMe function: $string\n";
}

sub PrintHello {
   print "String value inside PrintHello function: $string\n";
}

# Function calls
Printtutorialpro();
PrintHello();
print "String value outside functions: $string\n";

The output of the above program is:

String value inside PrintMe function: Hello, tutorialpro!
String value inside Printtutorialpro function: Hello, tutorialpro!
String value inside PrintHello function: Hello, World!
String value outside functions: Hello, World!

Static Variables

The state operator is similar to the static modifier in C; it makes local variables persistent.

state variables are also lexical variables, so they are valid only within the lexical scope where they are defined. Here's an example:

Example

#!/usr/bin/perl

use feature 'state';

sub PrintCount {
   state $count = 0; # Initialize the variable

   print "Counter value is: $count\n";
   $count++;
}

for (1..5) {
   PrintCount();
}

The output of the above program is:

Counter value is: 0
Counter value is: 1
Counter value is: 2
Counter value is: 3
Counter value is: 4

>

Note 1: state can only create variables with a scope limited to the subroutine.

Note 2: state was introduced in Perl 5.9.4, so it must be enabled with use.

Note 3: state can declare scalars, arrays, and hashes. However, arrays and hashes cannot be initialized (at least not in Perl 5.14).


Context of Subroutine Calls

Subroutine calls return different types of values depending on the context, such as the localtime() subroutine, which returns a string in scalar context and a list in list context:

Example

#!/usr/bin/perl

# Scalar context
my $datestring = localtime( time );
print $datestring;

print "\n";

# List context
# $year counts from 1900
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
printf("%d-%d-%d %d:%d:%d", $year + 1900, $mon + 1, $mday, $hour, $min, $sec);

print "\n";

The above program outputs the following result:

Sun Jun 12 15:58:09 2016
2106-6-12 15:58:9
❮ Perl Formats Perl Intro ❯