In this article let us review how to reference and dereference Perl array with examples. Reference is nothing but the location ( address ) of another variable. The references can be of array, or hash, or a snippet of Perl code. References makes the Perl code to run faster.
Perl Reference To Array
Normally, we store the list of elements in an array as shown below.
@array = (“one”,”two”,”three”,”four”,”five”);
To assign an array reference into a variable, use the backslash(\) operator as shown below
$array_ref = \@array;
If you try to print the $array_ref variable, you’ll get something like the following.
ARRAY(0x1a2b3c)
The Perl array reference can also be passed to a subroutine as shown below.
sub add_numbers { my $array_ref = shift; ..... } @numbers = (11,2,3,45); $array_ref = add_numbers(\@numbers);
In the above code snippet, we need to de-reference the array, so that the subroutine can take the elements from the original array.
Following are some of the advantages of passing the reference to a subroutine, instead of passing the whole array.
- If we passed the array to a subroutine, Perl copies the entire array into the @_ variable. When the array is big, this is not an effective method.
- When we want the original array to be modified by the subroutine, we need to pass the reference of the array.
- References plays essential role in constructing complex data structures.
We can take the reference of an Anonymous Array into the scalar variable as shown below.
$array_ref = [ 11,2,3,45];
Note: This article is part of the on-going Perl Tutorial series.
Perl Dereference Array
Inside the subroutine, the dereference can be done using one of the methods shown below.
The reference variable can be dereferenced as shown below. Using this method, we can take all the elements of the array. This is same as @numbers.
@{ $array_ref };
To obtain a particular element in an array, do the following. This statement gives the first element of @numbers array. This is same as $numbers[0]
$ { $array_ref }[0]
Instead of storing the reference into the variable, the array elements can be accessed directly from Perl built-in variable.
# Get all the elements of @numbers array. @ { $_[0] } # Get a particular element. This gives the first element of the array. $ { $_[0] } [0]
Note : If we are dereferencing a simple scalar variable, then we can omit the braces as shown below.
@$array_ref # same as @{ $array_ref } $$array_ref # same as $ { $array_ref } $_[0] # not a simple scalar variable and this cant be dereferenced,
Storing Multiple References into the Perl Array
Let us use the following sample Perl code snippet.
#Array contains source ip and destination ip @IP = ('192.168.1.10','192.168.1.15'); #Array contains the source port and destination port numbers @PORT = ("5000","5002"); #Sublayers of TCP layer @TCP = ("Q931","H225","H245"); #Common layers are available in a TCP packet. @LAYER = ("ETHERNET","IP",\@TCP); @PKT = ( \@IP, \@PORT, \@LAYER ); #Storing the reference of @PKT array into the scalar variable. $array_ref = \@PKT;
To understand the array referencing, let us assume that from the above code snippet, we want to access the second sublayer(“H225”) of TCP layer. This can be done as explained below.
First, we have to access the LAYER array. This returns a reference of @LAYER array.
$ { $array_ref } [2]
The $array_ref is a simple scalar variable. So, the braces can be omitted and it can also be written as shown below.
$$array_ref[2]
Next, to access the third element/layer (from @LAYER) through this reference.
$ { $ { $array_ref } [2] } [2]
This returns the address of @TCP array.
Finally, we can obtain the second sublayer of TCP layer (from @TCP array) as shown below.
$ { $ { $ { $array_ref } [2] } [2] } [1]
The above looks pretty complicated and reduces the modularity of the code. There is a provision to rewrite the above statements and makes it easier on the eyes by the following way.
In Perl, $ { VAR } [ $y] can be written as VAR->[$y].
$ { $array_ref } [2] is same as $array_ref->[2] $ { $ { $array_ref } [2] } [2] is same as $array_ref->[2]->[2] $ { $ { $ { $array_ref } [2] } [2] } [1] is same as $array_ref->[2]->[2]->[1]
Now, using the “drop arrow” rule, we can rewrite it as shown below. As per the “drop arrow” rule, we can not remove the first arrow. This is much easier to read.
$array_ref->[2][2][1]
Comments on this entry are closed.
Brilliant explanation. This has been the best material on perl refs I have yet seen, cleared up a lot of confusion with very little effort. Thanks
Very good explanation. Can you elaborate some examples, where do i use references ans where do i use simple variables?
it is too good
it is too good in writen
gr88888 explanation:)
excellent well explained, so easy to understand…thank you
It has been of great help. Only one thing missing is how to find length of array ($#arr) from array reference ( scalar(@{$arrRef}).
Great work!!!
Nice article. Thank you!
Thanks for this, it helped!
Hello, Thank you for posting this useful resource! I am writing macros for a custom game client called Open Kore.
In my macro I have successfully obtained Item coordinates and plugged them into a variable within a loop counter. My problem is plugging that variable into an array, and having the array element it delcares, change each time it loops.
here is my code. at the bottom the “set @ix[$cntr] $itemx” lines are wrong I know. I just havent figured out a correct way to plug $itemx & $itemy into an array.
macro buildarray {
$cntr = 0
while ($.hp > 400) as itemscan
[
:scan
$itemname = @eval($::items{$::itemsID[$cntr]}->{name})
if ($itemname == Opal) goto cc
if ($itemname == Cursed Ruby) goto cc
if ($itemname == Steel) goto cc
if ($itemname == Fang) goto cc
if ($itemname == Wind of Verdure) goto cc
if ($itemname == Rough Elunium) goto cc
if ($itemname == Rough Oridecon) goto cc
if ($itemname == Zenorc’s Fang) goto cc
if ($itemname == Orc’s Fang) goto cc
if ($itemname == Skel-Bone) goto cc
$cntr++
]
end itemscan
while ($.hp > 400) as coordcompile
[
:cc
$itemx = @eval($::items{$::itemsID[$cntr]}->{pos_to}{x})
$itemy = @eval($::items{$::itemsID[$cntr]}->{pos_to}{y})
log Item # – $cntr – $itemname
log @ coordinate X- $itemx,Y- $itemy
set @ix[$cntr] $itemx
set @iy[$cntr] $itemy
$cntr++
goto scan
]
}
This is nice article… got the deference clearly….. Hats off….