Saturday, March 20, 2010

Howto declare variables

So today we will look at the various options we have to declare a variable and how to decide which one to use. Primarily we will discuss the difference between use vars, our, my and local. I have quite often been confused as to when to use my and when to use our so I will elaborate a bit more on their differences in this article.

For the sake of this document I am using the following terms in the below mentioned context
declare: Associates a name with a variable - your perl interprator knows there is a variable to be used.
define: Actually allocate storage for the variable - if it was defined earlier the variable will lose that old definition.

my: This will declare and define a variable local to the block file or eval. Almost always you want to do this for all your variables unless you have a specific reason to do otherwise. If you define it outside any block in a Perl script the variable is global in scope to the whole file. my variables aren't associated with any package. The outcome of this type of declaration is that you can't access this file from another package. If you re-declare a variable it will create another instance of the variable in the current scope with the new data. Once it goes out of scope the variable reverts to the original value.

our: This will atleast declare a variable and if you wish it can also define a variable. You would primarily encounter the use of our variables while using global variables defined outside the scope of the current files - usually things like @INC and @ISA under the use strict pragma or while accessing global variables defined in a different namespace. You need to define only once in the scope - all other declaration for our in the file would use this definition. You also don't need to declare it more than once in a file if defined at the top level since our is global to the file unless restricted by scoping. This behavior results in the unintended consequence of a our variable changing the value in one function affecting globally even though you did a our in another function.

use vars: This will declare a variable inside a package - you can't do a use vars outside a package. The only place use vars would behave differently from a our variable is when you have multiple packages in a .pm file. The our variable will be globally declared across all packages whereas the use vars variable would be local to the package it was defined.

local: This will re-declare a variable in the enclosing block, file, or eval with the new initialized data if any. In most cases you want to do a my instead of a local as that is faster and considered safer. The only reason you want to do a local is if you are localizing a special variable or a global variable to use a different value in the current scope.


To highlight the difference between my and our I would like to quote from http://stackoverflow.com/questions/845060/what-is-the-difference-between-my-and-our-in-perl which says

Available since Perl 5, my is a way to declare:
    * non-package variables, that are
    * private,
    * new,
    * non-global variables,
    * separate from any package. So that the variable cannot be accessed in the form of $package_name::variable.

On the other hand, our variables are:
    * package variables, and thus automatically
    * global variables,
    * definitely not private,
    * nor are they necessarily new; and they
    * can be accessed outside the package (or lexical scope) with the qualified namespace, as $package_name::variable.


A good example to demonstrate the difference between my and our is as follows

$ cat test.pl
require "rt.pl";
print $hello . "\n";
$ cat rt.pl
our $hello = 'world';
$ perl t.pl
world

Changing the our $hello to my $hello would result in nothing being printed. The reason being our made the variable part of the main package whereas my stayed localized to rt.pl and nothing outside it could access the variable.

No comments:

Post a Comment

Followers