Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

Having finally grown comfortable with my own understanding of lexical and package variables(oh, and local too), I figured I'd take a shot at sharing my understanding with the average newbie that may be struggling with these concepts.

First off, I'd like to say that it was Damian Conway's Book, Object-Oriented Perl, that cleared things up with his explanation. Incidentally, this book can be purchases right through Perlmonks, by going here. And with that...

Package Variables
Package variables all belong to a package, even if only the main package. They can be called from anywhere within this package at any time, including sub-routines which may have been called from within that package.


$var = "foo";
print $var, "\n";

print $var, "\n";

sub modify_var {
    $var = "bar";


The output from this code demonstrates the ability of package variables to be accessed anywhere in the current package. $var is being accessed in both the main body of the program, and in the modify_var sub-routine.

In cases where package ownership is important, such as when strict is being used, the package and double colon can be appended after the prefix symbol($,@,%) and before the variable name:


use strict;

$main::var = "foo";
print $main::var, "\n";

print $main::var, "\n";

sub modify_var {
    $main::var = "bar";

NOTE: When strict is in use and the package name is not used to fully qualify the variable, this error will be reported:
Global symbol "$var" requires explicit package name at line n.
Execution of aborted due to compilation errors.
Where n is the line number of the innappropriately accessed variable. Declaring the variable with the my qualifier will fix the problem also. This will create a lexical variable, which will be talked about later.

In cases where the main package is in ownership of the variable, the actual word 'main' can be ommitted to yield something like: $::var

UPDATE: One more point on Package variables. It is possible to get around having to fully qualify variable names when strict is in use. Applying a simply use vars to your script, with the variable names as it arguments will get around explicit package names. Example:

#!/usr/bin/perl use strict; use vars qw($foo); $foo = "bar"; print $foo, "\n";

Lexical Variables
Lexical variables must be explicitly declared using the my qualifier. Lexical variables belong to no package so cannot be fully qualified with a package name. They can be accessed only within the current block, or, only within the curly braces or file scope in which they are declared. They cannot be accessed by sub-routines called from within the current code block.

Let's look at the first code example, but use lexical variables where previously there were package variables:


my $var = "foo";
print $var, "\n";

print $var, "\n";

sub modify_var {
    my $var = shift;
    $var = "bar";

Output from this code demonstrates that localization of the lexical variables. $var in the main package is treated as a completely different variable than $var in the modify_var sub-routine.

As was previously noted, using the my qualifier when strict is in use will prevent the Global symbol "$var" requires explicit package name at line n. error. This is because once a variable has been declared lexical, it belongs to no package and does not exist in the package's symbol table. So, it cannot be fully qualified.

NOTE: I said before that lexical variables are destroyed when the code block in which they are declared ends. This is usually the case. However, when a reference to the lexical variable continues to exist outside of the code block, the lexical variable survives past the block. It will be destroyed as soon as all references to it are gone. This is due to a Perl behavior known as reference counting.

How Does local Fit In?
Truthfully, at this point, it doesn't seem to. I've read in another node that local is useful in ammending code written in Perl4, or when you want to modify one of Perl special variables(see man perlvar) such as $/.

In any case, a little bit on how local works.

local takes a package(global) variable and temporarily replaces its value for the duration of the block in which it is used, meanwhile storing the old value to be replaced when the block ends. Here's an example:

$var = "foo";
print $var, "\n";

if (1) {
    local $var = "bar";
    print $var, "\n";

print $var, "\n";

Check the output out. Inside the if block, $var is declared using local and initialized to "bar". So for the duration of that block $var is storing "bar". When the if block ends, the previous value "foo" is restored to $var.

When I was playing around with all this stuff, I realized that using my and lexical variables externally behaves the same way as local, that is, it only seems like it does. Internally they behave very differently. The point is, though, that using lexicals can get the desired "temporary value" result.

When Should I Use Package Variables, and When Should I Use Lexicals?
Package variables are okay for short or uncomplicated Perl scripts, when you don't have to worry about intruding on the variable namespace of other routines or packages. Lexical variables should be used for large more complex programs. In truth, I always use lexical variables at this point, just out of habit and because I'm always using strict.

That's it for me. There's my first tutorial. I hope it helps.

In reply to Lexical vs. Package Variables (With a little local thrown in) by dsb

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    talexb finishes writing a Cranky Old Man post, and hopes it will be taken in the spirit intended. :)
    [Corion]: We're happy to have you here, talexb!
    [talexb]: Thanks. :)

    How do I use this? | Other CB clients
    Other Users?
    Others studying the Monastery: (11)
    As of 2018-07-19 14:17 GMT
    Find Nodes?
      Voting Booth?
      It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

      Results (410 votes). Check out past polls.