Broad Network


Scope Variable Modifiers in Perl

Perl Scoping Part 2

Perl Course

Foreword: In this part of the series, I talk about the my, our and local modifiers that affect scoping of Perl variables.

By: Chrysanthus Date Published: 8 Nov 2015

Introduction

This is part 2 of my series, Perl Scoping. In this part of the series, I talk about the my, our and local modifiers that affect scoping of Perl variables. Deep down in Perl, these modifiers are predefined functions. Scope is where a variable can be accessed (seen). You should have read the previous part of the series before coming here, as this is a continuation.

Block
Scope in Perl is focus on the block. The block consists of statements in curly brackets. That is:

    {
        //statements
    }

The following constructs have blocks: if, foreach, while-loop, do-loop, sub, package and eval. Remember, in Perl, a block can be anonymous.

You can have nested blocks, as in:

    {
        //statements
        {
            //statements
        }
        //statements
    }

For example, inside a function definition block, you can have an if-block. Nesting can have many levels (e.g. nested nested tested block).

my
A variable declared inside a block with the my modifier cannot be seen or used outside that block. It can be seen and used inside its block. A variable declared inside a nested (inner) block, cannot be seen in the outer block. On the other hand, a variable declared in an outer block can be seen in the nested block. A variable declared outside all blocks can be seen inside a block and in nested blocks.

Try the following code:

use strict;

    my $str;

    foreach my $i (0..4)
        {
            $str = "book";
            my $va = "pen";
            print "$i $str and $va\n";
        }

The output is:

0 book and pen
1 book and pen
2 book and pen
3 book and pen
4 book and pen

The variable, $str, declared outside the block of the for-construct, can be seen in the block; it cannot be seen outside the block. The variable, $va, declared in the block of the for-construct, can be seen only in that block; it cannot be seen outside the block. The variable, $i, is declared in the parentheses of the for-construct. It is seen inside the block of the for-construct. The $i variable cannot be seen outside the parentheses and outside the for-block (construct). Remember, in Perl, foreach and for are synonymous.

A variable, declared in an outer block can be seen in any level of a nested block. A variable, declared in the innermost block, can be seen only in its particular innermost block. A variable not declared in any block, can be seen inside any block.

A variable declared outside a block can be seen inside the block. Well, there is a nuance to this rule: A variable declared outside a block can be replaced by a new declaration inside the block. Assume that you have a variable, $va, declared outside a block. If you declare a new variable inside a block with the same name, you will end up with two different variables: a $va that operates only outside the block and a $va that operates only inside the block. Try the following code:

use strict;

    my $str;
    my $va = "pen";

    foreach my $i (0..4)
        {
            $str = "book";
            my $va = "pencil";
            print "$i $str and $va\n";
        }

The output is:

0 book and pencil
1 book and pencil
2 book and pencil
3 book and pencil
4 book and pencil

You have pencil and not pen, as might have been expected at the output.

Here is a quotation from the Perl manual: A my declares the listed variables to be local (lexically) to the enclosing block, file, or eval. If more than one value is listed, the list must be placed in parentheses.

our
The our modifier behaves in a similar way to the my modifier, except that it can be seen outside the block. However, to access it outside the block, you have to use the package name. The package of an ordinary executable Perl file is main. Try the following code:

use strict;

    if (22==22)
        {
            our $man = "John";
        }

print $main::man;

The output is,

    John

Package Block
As indicated above, a my variable in a block cannot be seen outside the block, while an our variable can be seen outside the block, if you use the package name to access it. Since you will be using package block to create a class, you have to bare in mind this: a my variable declared inside a package block cannot be seen outside the package block, while an our variable declared inside the package block can be seen outside the package block if you use the package name to access it. The following code will give an error message:

use strict;

    {package Pac;

        my $woman = "Mary";
    }

print $woman;

The following code will print the our variable:

use strict;

    {package Pac;

        our $man = "John";
    }

print $Pac::man;

The output is:

    John

Concerning the my modifier and package, even if you use the package name, the value will still not be printed.

File Scope
A my variable declared inside a block, cannot be seen outside the block. A my variable declared outside all blocks, in a file, is seen throughout the whole file, in all blocks, including nested blocks, except re-declared in a nested block (ending up with a new variable). The my variable cannot be seen outside a file (in a different file). The my variable operates in file scope.

The our variable operates like the my variable but with the following differences: An our variable declared inside a block, can be seen outside the block if accessed with the package name. An our variable declared outside all blocks, in a file, is seen throughout the whole file, in all blocks, including nested blocks, except re-declared in a nested block (ending up with a new variable). The our variable can be seen outside a file (in a different file) if accessed with the package name. The our variable operates beyond file scope.

In a different series, I will explain how to access a variable of one file in a different file.

main
The package name of an ordinary executable Perl file is called, main. You can imagine such a complete file enclosed in curly brackets, {} .

local
local is a scope variable modifier. It operates like the my modifier, but it is hardly used. When should you then use the local modifier? local affects the value of a variable inside a block. There are three situations in which you have to use the local modifier:

1) You want to temporarily change just one element of an array or hash.
2) You need to give a special variable, e.g. $/, a temporary value.
3) You need to create a local file handle or directory handle or a local function see later.

The following code illustrates the application of the first point using an anonymous block:

use strict;

    my @animals = ('dog', 'cat', 'parrot');

    print "$_ " foreach @animals; print "\n";
    
    {
        local $animals[1] = 'snake';
        print "$_ " foreach @animals; print "\n";
    }

    print "$_ " foreach @animals; print "\n";

The output is:

    dog cat parrot
    dog snake parrot
    dog cat parrot

If you remove the local modifier in the block, the last print will have snake in place of cat.

The following code illustrates the application of the second point using an anonymous block. This code reads a text file, paragraph-by-paragraph. It does so by temporarily changing the default value of $/, which is \n, to \n\n, in the block.

use strict;

    open(fHandle, "<", "myFile.txt") or die "cannot open myFile.txt : $!";

    my @arr;

    {
        local $/ = "\n\n";
        @arr = <fHandle>;
    }

    close fHandle;

    my $var = @arr;
    print $var;

    undef @arr;

The output is the number of elements in the array, meaning that the paragraphs where read as lines.

Concerning the third point, I will talk about that later.

That is it for this part of the series. We take a break here and continue in the next part.

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