The $_ and @_ Special Variables in Perl
Perl Basics – Part 14
Perl Course
Foreword: In this part of the series, I introduce you to two special variables in Perl; I also explain their use in a function.
By: Chrysanthus Date Published: 29 Mar 2015
Introduction
Two Examples
In this part of the series, we look at two of the variables, which are $_ and @_ . The former is a scalar; the later is an array. The later was mentioned in one of the previous parts of the series. The name of the former is _ . It is preceded by $ since it is a scalar. The name of the later is also _ . It is preceded by @ since it is an array. There are many such variables already declared for you in the Perl interpreter.
The way you will declare your own variable, is just to begin with the reserved word, my, then a space, followed by $, @ or % and them the name of the variable, then a semicolon to make a statement. After that as you write your code your variable will acquire value (or values) depending on the code you write. These special variables behave in a similar way, with the difference that they have already been declared for you in the interpreter. Also, the conditions under which they will acquire certain values have already been determined in the interpreter. The particular values they acquire depend on the condition. You learn the conditions and the acquired values as you learn Perl. You are not the one who gives them values. It is the interpreter that gives them values. In this part of the series, we learn the conditions and acquired values for $_ and @_ . We learn just some of the conditions, not all.
The names of these special variables are like punctuation signs. Some of them are actually punctuation signs, like with $?. Do not worry about $? for now. In general the names of these variables are not likely the names you would give to your own user declared variables. You normally would give a name to a variable that you can remember, like in @books, where you want books to mean an array of books. So hardly would there be conflicts between your variables and these special variables.
The syntax for the foreach construct is,
foreach Vairable (List)
{
#do something
}
If Variable (which is a scalar) in the syntax is not typed, then $_ would take its place. You can then use $_ inside the block as you would use, Variable. Consider the following code fragment:
foreach my $item (@theArr)
{
print $item, "\n";
}
If you do not type the $item variable, then the special variable, $_ would take the place of the $item variable. The block of the code would have to be written as,
foreach (@theArr)
{
print $_, "\n";
}
$item was not typed in the first line of the construct, so inside the block, $_ was used in its place. Try the following code:
use strict;
my @theArr = ("HBWE", "FGTR", "HTNK", 4587, 4526, 4053, "AB12", "GB58", "TG45", "RE69");
foreach (@theArr)
{
print $_, "\n";
}
I hope you now appreciate a condition and values in the way $_ has behaved. There are other situations in Perl where $_ is used. The situations are similar to this one.
When you call a subroutine (function) with arguments, when the function is being executed, all the arguments will be members of the special variable, @_ . So, within a subroutine the array @_ contains the arguments passed to that subroutine. This array variable has already been pre-declared in the interpreter. You do not have to declare it again. Whenever a subroutine is called, the values of this array become the values of the arguments passed to the subroutine. The array @_ is filled, beginning from the first index (0). If the subroutine is called without arguments, then the array will be empty. Try the following code:
use strict;
sub mySub
{
print $_[0], "\n", $_[1], "\n", $_[2];
}
mySub("one", "two", "three");
The subroutine is called with three arguments ("one", "two", "three"). When the subroutine is executed, the value of the first element of @_ is the value of the first argument, the value of the second element is the value of the second argument, and that of the third element is the value of the third argument. If there were more arguments, fourth element will be fourth argument, firth element will be fifth argument, and so on.
Note: Since the name of the array, @_ , is _ , the elements of the array, are $_[0], $_[1], $_[2], etc.
The question you may have is this: what happens if the argument passed is an array or a hash. If the argument is an array or a hash, in the function, it collapses (becomes flat) losing its identity and its items become values of the @_ array. Let us demonstrate this with an experiment.
Read and try the following code:
use strict;
my $scal = "one";
my @arr = ("two", "three");
my %hsh = (
DDD => "four",
EEE => "five"
);
sub mySub
{
print @_;
}
mySub($scal, @arr, %hsh);
I tried the code in my computer and I had the following as result:
onetwothreeEEEfiveDDDfour
The values are not separated by commas or spaces; let us allow things like that for now. The first argument in the call, is $scal, and its value is the first in the @_array. That is OK. The second argument is @arr. It has values "two" and "three" in that order. The second and third values in the @_ array are "two" and "three". So far as order in the arguments (scalar, or array) are concerned, the order in which the values go to the @_ array is the way they were sent.
Now the keys and the values for the hash became values of the @_ array, but not in the order in which the hash was created. The order of key and value, within a key/value pair is maintained. However, the order of the key/value pairs are not necessarily maintained.
We see that even though, inside a subroutine, arrays and hashes are collapsed, the positioning of the scalar arguments are maintained in the @_ array; the internal order for array arguments is also maintained, but the internal order for hash pairs is not necessarily maintained. That is just how it is, with Perl.
Read and try the following code for a hash:
use strict;
my %fruitColor = (
Apple => "purple",
Banana => "yellow",
Pear => "green",
lime => "light green"
);
sub mySub
{
foreach (@_)
{
print $_, "\n";
}
}
mySub(%fruitColor);
I tried it and I had:
Pear
green
Apple
purple
lime
light green
Banana
Yellow
As you can see again, the pairs order is not necessarily maintained, but the order within a value pair is maintained. Also note that for a key/value pair, the key takes an element in the @_ array, and the value takes the next element in the array.
Instead of sending an array variable or hash variable as argument, you can send the literal list. For the hash, this has the advantage of maintaining the pairs order. The order within key/value is still maintained for the hash; however, it is still one key per element and one value per element. Try the following code:
use strict;
my $scal = "one";
sub mySub
{
foreach (@_)
{
print $_, "\n";
}
}
mySub($scal, ("two", "three"), (DDD => "four", EEE => "five"));
I tried the code several times and I had the same:
one
two
three
DDD
four
EEE
five
If you do not want the array variable or hash variable as argument to collapse, then you have to use the array reference or hash reference. In that case the array will not collapse and the element order will be maintained; the hash will also not collapse, but the pairs order will not necessarily be maintained – see later.
Time to take a break! We stop here and continue in the next part of the series.
Chrys
Related Links
Perl BasicsPerl Data Types
Perl Syntax
Perl References Optimized
Handling Files and Directories in Perl
Perl Function
Perl Package
Perl Object Oriented Programming
Perl Regular Expressions
Perl Operators
Perl Core Number Basics and Testing
Commonly Used Perl Predefined Functions
Line Oriented Operator and Here-doc
Handling Strings in Perl
Using Perl Arrays
Using Perl Hashes
Perl Multi-Dimensional Array
Date and Time in Perl
Perl Scoping
Namespace in Perl
Perl Eval Function
Writing a Perl Command Line Tool
Perl Insecurities and Prevention
Sending Email with Perl
Advanced Course
Miscellaneous Features in Perl
Perl Two-Dimensional Structures
Advanced Perl Regular Expressions
Designing and Using a Perl Module
More Related Links
Perl Mailsend
PurePerl MySQL API
Perl Course - Professional and Advanced
Major in Website Design
Web Development Course
Producing a Pure Perl Library
MySQL Course
BACK NEXT