Perl | References to a Subroutine
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
sub name
{
return "GeeksforGeeks" ;
}
$rs1 = \&name;
print ( "Reference to named subroutine: " , $rs1 );
print ( "\nAfter dereferencing, value : " , & $rs1 );
$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
$rs = \&func1;
$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" ;
}
|
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
sub alt {
print "$a $b\n" ;
$arr { $a } cmp $arr { $b };
}
%arr = ( "Marcelo" , "Lewis" ,
"Rodrygo" , "Peter" ,
"Sandro" , "James" );
@names = calc ( "Alternate" , keys ( %arr ));
foreach $person ( @names )
{
print "$person teams up with $arr{$person}\n" ;
}
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
$array = [[1, 2, 3, 4, 5],
[ 'Geeks' , 'for' , 'Geeks' ],
[6, 7, 8, 9]];
print ( "$$array[1][2]" );
print ( "\n$array->[1][1]" );
print ( "\n$array->[1]->[0]" );
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
use strict;
use warnings;
my %friends = ( 1 => 'John' , 4 => 'Sandro' ,
2 => 'Rodrygo' , 5 => 'Peter' ,
3 => 'Marcelo' , 6 => 'Luis' );
my $hash_ref = \ %friends ;
print ( "$$hash_ref{1}\n" );
print ( "$hash_ref->{3}\n" );
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
Share your thoughts in the comments
Please Login to comment...