Open In App

Perl | References to a Subroutine

Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisite: Perl references
 

Declaring References to a Subroutine

In Perl, a reference is, exactly as the name suggests, a reference or pointer to another object. References actually provide all sorts of abilities and facilities that would not otherwise be available and can be used to create sophisticated structures such as Dispatch tables, Higher-order procedures, Closures, etc. For C programmers using Perl for the first time, a reference is exactly like a pointer, except within Perl it’s easier to use and, more to the point, more practical. There are two types of references: symbolic and hard
Symbolic reference enables you to use the value of another variable as a reference to a variable by name. For example, if the variable $val contains the string “Text”, the symbolic reference to $val refers to the variable $Text. 
A hard reference is a term for actual data that is contained in a data structure. However, the form of the data structure to which it points is largely irrelevant. Although a hard reference can refer to a single scalar, it can also refer to an array of scalars, a hash, or a subroutine.

$val = "Text";
$val_ref = \$val;

# For other variables
$array = \@ARGV;
$hash = \%ENV;

# For reference to subroutine
sub val { print "val" };
$valsub = \&val;

 

Calling a subroutine Reference

Calling a subroutine reference is also known as dereferencing. It is the act of extracting information from the structures. When you dereference a scalar reference, you are in fact referring to the original data structure. The most direct approach of dereferencing a reference is to prepend the relevant data type character ($ for scalars, @ for arrays, % for hashes, and & for subroutines) that you simply expect before of the scalar variable containing the reference.

$val_ref = \$val;       # Create reference to scalar
$array = \@ARGV;        # Create reference to array
$hash = \%ENV;          # Create reference to hash
$valsub = \&            # Create reference to subroutine

# Dereferencing
$$val_ref;
$$array[0, 1, ....];
$$hash{'...'};
&$valsub;

 

Note: The act of dereferencing information must be explicit. There is no implicit dereferencing supported within Perl on any structure.

Subroutines can be both named as well as anonymous. Perl provides the facility to declare references to both the types of subroutines and to dereference them. 
Example 1: 

perl




#!/usr/bin/perl
 
# Perl program to demonstrate
# reference to subroutines
 
# Creating a named subroutine
sub name
{
    return "GeeksforGeeks";
}
 
# Create callable reference
# to named subroutine
$rs1 = \&name;    
print("Reference to named subroutine: ", $rs1);
print("\nAfter dereferencing, value : ", &$rs1);
 
# Create a reference to an
# anonymous subroutine
$rs2 = sub{
               return "GFG";
          };
print("\n");
print("\nReference to anonymous subroutine: ", $rs2);
print("\nAfter dereferencing, value : ", &$rs2);


Output

Reference to named subroutine: CODE(0x981750)
After dereferencing, value : GeeksforGeeks

Reference to anonymous subroutine: CODE(0x981870)
After dereferencing, value : GFG

The use of infix operation is shown in the below example. The infix operation provides a better and easier way of extracting information from the complex or nested structures.
Example 2: 

perl




#!/usr/bin/perl
 
# Perl program to demonstrate
# reference to subroutines
 
$rs = \&func1;
 
# Prints "GeeksforGeeks"
$rs->("Geeks")->("for")->("Geeks");    
 
sub func1
{
    my $val = shift;
    print "$val";
    return \&func2;
}
 
sub func2
{
    my $val = shift;
    print "$val";
    return \&func3;
}
 
sub func3
{
    my $val = shift;
    print "$val\n";
}


Output: 

GeeksforGeeks

 

Callbacks

Callbacks is one of the important element that one should remember when developing Perl Tk interfaces. It calls back a piece of code from another part of the script when we reach a certain point of condition or perform a certain action. 
Callbacks are somewhat like a delayed execution of code, which is triggered by an event instead of executing things in a linear way. For such event-driven functionality of code, we often make use of subroutine references to call such pieces of code when required.
Example: 

Perl




# Perl program to demonstrate
# the use of callbacks
sub alt {
            print "$a $b\n";
            $arr{$a} cmp $arr{$b};
        }
 
%arr = ("Marcelo", "Lewis",
        "Rodrygo", "Peter",
        "Sandro", "James");
 
# @names = sort alt (keys(%arr));
@names = calc ("Alternate", keys(%arr));
foreach $person (@names)
{
    print "$person teams up with $arr{$person}\n";
}
 
# Example code to show
# what really goes on inside sort.
sub calc
{
    my ($subn, @final) = @_;
    for ($k = 0; $k < $final; $k++)
    {
        $count = 0;
        for ($j = 0; $j < $final - $k; $j++)
        {
            $a = $final[$j];
            $b = $final[$j + 1];
            if (&{$subn}() > 0 )
            {
                $final[$j] = $b;
                $final[$j + 1] = $a;
                $count++;
            }
        }
        last unless ($count);
    }
    return @final
}


Output: 

Sandro teams up with James
Rodrygo teams up with Peter
Marcelo teams up with Lewis

 

The above example depicts the sorting of a list of hash keys based on the number of characters (length) in the value held in the hash using a callback function calc.
 

Arrays and Hashes of References

Beyond the normal constraints of arrays and hashes, you can also create complex structures made up of combinations of the two. These are nested, or complex structures and they can be used to model complex data in an easy-to-use format. What actually happens with a nested structure is that Perl stores the nested data type as a reference to an anonymous variable. For example, in a two-dimensional array, the main array is a list of references, and the sub-arrays are anonymous arrays to which these references point. This means that an “array of arrays” actually means an array of references to arrays. The same is true for all nested structures; and, although it seems complex, it does provide a suitably powerful method for creating complex, nested structures.
Example 1: 

perl




w
# Perl program to demonstrate
# array of references
 
# Declaring a reference to a nested array
$array = [[1, 2, 3, 4, 5],
          ['Geeks', 'for', 'Geeks'],
          [6, 7, 8, 9]];
 
# Access element using index
# Dereferencing performed
print("$$array[1][2]");    
 
# Access element using infix method
print("\n$array->[1][1]");
print("\n$array->[1]->[0]");
 
# Printing complete nested array
print("\nElements in the array are :");
print("\n");
for(my $i = 0; $i < scalar(@{$array}); $i++)
{
    for(my $j = 0; 
           $j < scalar(@{$array->[$i]}); $j++)
    {
        print($$array[$i][$j]);
        print(" ");
    }
    print("\n");
}


Output: 

Geeks
for
Geeks
Elements in the array are :
1 2 3 4 5 
Geeks for Geeks 
6 7 8 9

 

Example 2:

perl




#!/usr/bin/perl
 
# Perl program to demonstrate
# array of references
use strict;
use warnings;
 
my %friends = ( 1 => 'John',     4 => 'Sandro',
                2 => 'Rodrygo', 5 => 'Peter',
                3 => 'Marcelo', 6 => 'Luis' );
 
# Declaring a Reference to the hash
my $hash_ref = \%friends;
 
# Access element from hash using key value
print("$$hash_ref{1}\n");     # prints John
 
# Access element using infix operation
print("$hash_ref->{3}\n");
 
# Print all elements of the hash
# with their keys
print ("The hash stored is :\n");
 
for (keys %$hash_ref)
{
    print("$_ = $hash_ref->{$_}\n");
}


Output: 

John
Marcelo
The hash stored is :
4 = Sandro
1 = John
2 = Rodrygo
5 = Peter
3 = Marcelo
6 = Luis

 



Last Updated : 10 Jul, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads