Broad Network


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

This is part 14 of my series, Perl Basics. In this part of the series, I introduce you to two special variables in Perl; I also explain their use in a function. These are variables that have already been declared in the Interpreter for you. You do not have to declare them again. Under certain conditions, the variables acquire certain values. As you learn Perl, you learn the names of these variables and other special variables; you also learn the values they acquire and the conditions under which they acquire the values. Any of these variables fall into one of the three data types. So any of these variables is a scalar or an array or a hash. You should have read the previous parts of the series before reaching here, as this is a continuation.

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 $_ Variable
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.

The @_ Variable
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.

Passing Lists as Arguments to Subroutines
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.

Array and Hash Argument Literals
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 Basics
Perl 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

Comments

Become the Writer's Fan
Send the Writer a Message