Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

use vars in a require()d file

by sacked (Hermit)
on Mar 12, 2001 at 04:53 UTC ( [id://63704]=perlquestion: print w/replies, xml ) Need Help??

sacked has asked for the wisdom of the Perl Monks concerning the following question:

Here is foobarbaz.pl, which sets some default values:
#!/usr/local/bin/perl -w # use strict; use diagnostics; use vars qw( $qux $quo $zip ); $foo = 1; $bar = 2; $baz = 3; $qux = 4; $quo = 5; $zip = 6; sub hello { print "Hello, World!\n" }
And here is program.pl:
#!/usr/local/bin/perl -w # use strict; use diagnostics; use vars qw( $foo $bar $baz ); require 'foobarbaz.pl'; # OK, but need package name for $qux, $quo, $zip print "$_\n" foreach( $foo, $bar, $baz, $::qux, $::quo, $::zip ); hello(); # fine #print $qux; ## XXX gives an error while (my ($k,$v) = each %:: ) { print $k . ":\t\t" . $v . "\n"; }
In program.pl, when printing the symbol table, the identifiers for $qux, $quo, $zip appear in main's symbol table, but I can only access them by explicitly providing the package name. This throws a warning, however: Name "main::zip" used only once: possible typo at require.pl line 11 (same warning for $qux and $quo).

Normally, when using a separate file to initialize variables, I would declare all the variables in program.pl with use vars (or make the separate file a module that uses Exporter). I was just curious to see the effects of use vars in a require()d file. I do not understand why the identifiers exist in main's symbol table, but appear 'hidden' to an extent. Can anyone enlighten me?

Thanks much!
--sacked

Replies are listed 'Best First'.
Re: use vars in a require()d file
by chromatic (Archbishop) on Mar 12, 2001 at 05:52 UTC
    require fires at run-time. Until then, Perl has no way of knowing that you've declared your variables in the other file.

    Luckily, a BEGIN block will fix things:

    BEGIN { require 'foobarbaz.pl'; }
    It's not that the variables are hidden, it's just that Perl doesn't see them in time to avoid the warning, unless you tell the compiler to read the file before it does the warning check.
Re: use vars in a require()d file
by athomason (Curate) on Mar 12, 2001 at 05:58 UTC
    From perlman:lib:vars:
    Unlike pragmas that affect the `$^H' hints variable, the `use vars' and `use subs' declarations are not BLOCK-scoped. They are thus effective for the entire file in which they appear. You may not rescind such declarations with `no vars' or `no subs'.

    Note the phrase entire file. So, when you declare $qux, $quo, and $zip in foobarbaz.pl, perl has already forgetten that they were declared via use vars by the time you get around to reading them in program.pl. However, the symbol table is more permanent, which is why you can still access them by explicitly specifying package main.

    Update

    Whoops, guess you shouldn't always believe the docs... it does look like the behavior follows chromatic's explanation.

      chromatic is right. However the documentation for vars should be updated to make it clear that a vars declaration is actually package scoped, not file scoped. In other words that global has been declared, and will be considered declared in every file you encounter from then on as long as they are all in the same package. Of course if you are following good Perl tradition and writing lots of modules with private packages, the issue won't come up...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://63704]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2024-04-24 02:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found