The source code for vars is not totally impenetrable. The first thing to recall is that use Foo qw(bar); is essentially the same thing as:

BEGIN{ require Foo; Foo->import('bar'); }

And the brief explanation of what import() typically does, is it makes some thing available within the caller's namespace. It exports something. In the case of my example, it exports a subroutine (probably) named bar. In the case of use vars qw($foo), it exports into the caller's namespace a package global scalar variable named $foo.

Now let's look at the import function from vars, which is invoked when use vars qw(...) is called:

sub import { # Determine the package name of the caller. my $callpack = caller; # Grab the list of symbols that need to be exported. my (undef, @imports) = @_; my ($sym, $ch); foreach (@imports) { # For each "var", find the sigil and the symbol. if (($ch, $sym) = /^([\$\@\%\*\&])(.+)/) { # If the symbol contains non-word characters... if ($sym =~ /\W/) { # time for a more-detailed check-up if ($sym =~ /^\w+[[{].*[]}]$/) { # We're being asked to declare an array or hash el +ement. That's not cool. require Carp; Carp::croak("Can't declare individual elements of hash or +array"); } elsif (warnings::enabled() and length($sym) == 1 and $sym !~ + tr/a-zA-Z//) { # If it's a special punctuation variable... warnings::warn("No need to declare built-in vars"); } elsif (($^H &= strict::bits('vars'))) { # If we're strict, disallow funky variable names. require Carp; Carp::croak("'$_' is not a valid variable name under stric +t vars"); } } # Build up the fully-qualified symbol name. $sym = "${callpack}::$sym" unless $sym =~ /::/; # Vivify the symbol name within the appropriate package/na +mespace. *$sym = ( $ch eq "\$" ? \$$sym : $ch eq "\@" ? \@$sym : $ch eq "\%" ? \%$sym : $ch eq "\*" ? \*$sym : $ch eq "\&" ? \&$sym : do { require Carp; Carp::croak("'$_' is not a valid variable name"); }); } else { # This is odd... we weren't given a sigil. require Carp; Carp::croak("'$_' is not a valid variable name"); } } };

That's it... some heuristics to decide what the fully qualified variable name should be, and then a little bit of symbol table trickery to make it exist.

use vars is useful because it makes the variable exist so that strict 'vars' doesn't get angry. It's an early form of pre-declaration. Other forms of pre-declaration include my and our. The first one (my) creates a lexical variable. our creates a package global and makes it available without using a fully qualified name, within the lexical scope in which our was invoked. vars is mostly oblivious to lexical scoping. It creates package globals, that's it.

The BEGIN block is usually used to control the order in which things happen as compiletime gets underway. By using vars in a begin block, most likely the author intended to have it happen in a specific order. use already happens during compiletime, but the BEGIN block can be used to fine tune the sequence of compiletime events.

I don't usually do "disclaimers", but... The dark art of symbol table manipulation and compiletime manipulation is difficult to express both in layman's terms and at the same time with sufficient precision as to not misrepresent anything. I apologize in advance if this post falls short in either endeavor.


Dave


In reply to Re: What does use vars qw{$VERSION}; do? by davido
in thread What does use vars qw{$VERSION}; do? by alwynpan

Title:
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, details, 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, summary, 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.