Copyright © tutorialspoint.com

# PERL Variable Types

Perl has three built in variable types:

- Scalar
- Array
- Hash

# Scalar variable type

A scalar represents a single value as follows:

     my $animal = "camel"; my $answer = 42;

Here my is a keyword which has been explained in the same section at the bottom.

A scalar values can be strings, integers or floating point numbers, and Perl will automatically convert between them as required. There is no need to pre-declare your variable types. Scalar values can be used in various ways:

    print $animal;
    print "The animal is $animal\n";
    print "The square of $answer is ", $answer * $answer, "\n";

There are a number of "magic" scalars with names that look like punctuation or line noise. These special variables are used for all kinds of purposes and they wioll be discussed in Special Variables sections. The only one you need to know about for now is $_ which is the "default variable". It's used as the default argument to a number of functions in Perl, and it's set implicitly by certain looping constructs.

     print;       # prints contents of $_ by default

# Array variable type:

An array represents a list of values:

    my @animals = ("camel", "llama", "owl");

    my @numbers = (23, 42, 69);

    my @mixed   = ("camel", 42, 1.23);

Arrays are zero-indexed but you can change this setting by changing default variable $[ or $ARRAY_BASE. Here's how you get at elements in an array:

    print $animals[0];              # prints "camel"
    print $animals[1];              # prints "llama"

The special variable $#array tells you the index of the last element of an array:

    print $mixed[$#mixed];       # last element, prints 1.23

You might be tempted to use $#array + 1 to tell you how many items there are in an array. Don't bother. As it happens, using @array where Perl expects to find a scalar value ("in scalar context") will give you the number of elements in the array:

    if (@animals < 5) { ... } # Here @animals will return 3

The elements we're getting from the array start with a $ because we're getting just a single value out of the array -- you ask for a scalar, you get a scalar.

To get multiple values from an array:

    @animals[0,1];          # gives ("camel", "llama");

    @animals[0..2];         # gives ("camel", "llama", "owl");

    @animals[1..$#animals]; # gives all except the first element

This is called an "array slice". You can do various useful things to lists as follows:

    my @sorted    = sort @animals;

    my @backwards = reverse @numbers;

    # Here sort and reverse are Perl's built-in functions

There are a couple of special arrays too, such as @ARGV (the command line arguments to your script) and @_ (the arguments passed to a subroutine). These are documented in next section "Special Variables".

# Hash variable type:

A hash represents a set of key/value pairs. Actaully hash are type of arrays with the exception that hash index could be a number or string. They are prefixed by % sign as follows:

    my %fruit_color = ("apple", "red", "banana", "yellow");

You can use whitespace and the => operator to lay them out more nicely:

    my %fruit_color = (
       apple  => "red",

       banana => "yellow",
    );

To get a hash elements:

    $fruit_color{"apple"};           # gives "red"

You can get at lists of keys and values with keys() and values() built-in functions.

    my @fruits = keys %fruit_colors;

     my @colors = values %fruit_colors;

Hashes have no particular internal order, though you can sort the keys and loop through them. Just like special scalars and arrays, there are also special hashes. The most well known of these is %ENV which contains environment variables.

More complex data types can be constructed using references, which allow you to build lists and hashes within lists and hashes. A reference is a scalar value and can refer to any other Perl data type. So by storing a reference as the value of an array or hash element, you can easily create lists and hashes within lists and hashes.

The following example shows a 2 level hash of hash structure using anonymous hash references.

    my $variables = {

       scalar  =>  {
          description => "single item",
          sigil => '$',

         },
       array   =>  {
          description => "ordered list of items",

          sigil => '@',
         },
       hash    =>  {

          description => "key/value pairs",
          sigil => '%',
         },

    };

Following line will print $

     print "$variables->{'scalar'}->{'sigil'}\n"    ;

# Variable Context:

PERL treats same variable differently based on Context. For example

    my @animals = ("camel", "llama", "owl");

Here @animals is an array, but when it is used in scalar context then it returnes number of elements contacined in it as following.

    if (@animals < 5) { ... } # Here @animals will return 3

Another examples:

    my $number = 30;

Here $number is an scalar and contained number in it but when it is called along with a string then it becomes number which is 0, in stead of string:

    $result = "This is " + "$number";
    print "$result";

Here output will be 30

# Escaping Characters:

In PERL we use the backslash (\) character to escape any type of character that might interfere with our code. Below is the example

    $result = "This is " . "\"number\"";
    print "$result";

Here output will be This is "number"

# Case Sensitivity:

Variable names are case sensitive; $foo, $FOO, and $fOo are all separate variables as far as Perl is concerned.

# Variable Scoping:

Throughout the previous section all the examples have used the following syntax:

    my $var = "value";

The my is actually not required; you could just use:

    $var = "value";

However, the above usage will create global variables throughout your program, which is bad programming practice. But my creates lexically scoped variables instead. The variables are scoped to the block (i.e. a bunch of statements surrounded by curly-braces) in which they are defined. Have a look at the following example:

    my $a = "foo";
    if ($some_condition) {

       my $b = "bar";
       print $a;    # prints "foo"

       print $b;    # prints "bar"
    }
    print $a;       # prints "foo"

    print $b;       # prints nothing; $b has fallen out of scope

Using my in combination with a use strict; at the top of your Perl scripts means that the interpreter will pick up certain common programming errors. For instance, in the example above, the final print $b would cause a compile-time error and prevent you from running the program. Using strict is highly recommended. Following is the usage:

    use strict;

    my $a = "foo";
    if ($some_condition) {

       my $b = "bar";
       print $a;    # prints "foo"

       print $b;    # prints "bar"
    }
    print $a;       # prints "foo"

    print $b;       # prints nothing; $b has fallen out of scope

# Private Variables via my():

The my operator declares the listed variables to be lexically confined to the following but not limited to

- Enclosing blocks,

- Conditional (if/unless/elsif/else)

- Loop (for/foreach/while/until/continue)

- Subroutine

- eval or do/require/use'd file

If more than one value is listed, the list must be placed in parentheses. All listed elements must be legal lvalues. Scoped--magical built-ins like $/ must currently be localized with local instead.

    my $foo;           # declare $foo lexically local
    my (@wid, %get); 	 # declare list of variables local
    my $foo = "flurp"; # declare $foo lexical, and init it
    my @oof = @bar;	 # declare @oof lexical, and init it
    my $x : Foo = $y;	 # similar, with an attribute applied

Lexical scopes of control structures are not bounded precisely by the braces that delimit their controlled blocks; control expressions are part of that scope, too. Thus in the loop the scope of $line extends from its declaration throughout the rest of the loop construct (including the continue clause), but not beyond it.

    while (my $line = <>) {
       $line = lc $line;
    }continue {
        print $line;
    }

Similarly, in the conditional the scope of $answer extends from its declaration through the rest of that conditional, including any elsif and else clauses, but not beyond it.

    if ((my $answer = <STDIN>> =~ /^yes$/i) {
         user_agrees();
    } elsif ($answer =~ /^no$/i) {
         user_disagrees();
    } else {
    chomp $answer;
         die "'$answer' is neither 'yes' nor 'no'";
    }

We encourage the use of lexically scoped variables. Use the following line at the top of your program file to avoid any error. This will remind you to scope the variable using local or my keyword.

    use strict 'vars';

# Temporary Values via local():

A local modifies its listed variables to be "local" to the enclosing block, eval, or do FILE --and to any subroutine called from within that block. A local just gives temporary values to global (meaning package) variables. It does not create a local variable. This is known as dynamic scoping.

Lexical scoping is done with my, which works more like C's auto declarations.

    local $foo;             # make $foo dynamically local
    local (@wid, %get);     # make list of variables local
    local $foo = "flurp";   # make $foo dynamic, and init it
    local @oof = @bar;      # make @oof dynamic, and init it

Because local is a run-time operator, it gets executed each time through a loop. Consequently, it's more efficient to localize your variables outside the loop.

If you localize a special variable, you'll be giving a new value to it, but its magic won't go away. That means that all side-effects related to this magic still work with the localized value. This feature allows code like this to work :

    # Read the whole contents of FILE in $slurp
    { local $/ = undef; $slurp = <FILE> ; }

Copyright © tutorialspoint.com