in reply to use strict and exporting package variables

The vars pragma does more than "exempting" variables from the strict pragma. It creates an entry in the current package's symbol table for the named variable.

That's important, because it's how you locate variables inside a package. (Variables declared with my or localized are bound to a particular lexical scope -- they don't live in the symbol table. I'm simplifying things here by ignoring what happens when you localize a variable in the symbol table.)

The upshot of it is, import works by creating an alias in the current package's symbol table to point to a thingie in another package's symbol table.

Since lexical variables don't live in a symbol table, that doesn't work.

The important thing to remember is that namespaces use symbol tables, which are not the same thing as lexical scopes. I can get away with this jargon because you mention the Camel. :)

  • Comment on Re: use strict and exporting package variables

Replies are listed 'Best First'.
(bbfu) (just to confuse the issue) Re(2): use strict and exporting package variables
by bbfu (Curate) on May 01, 2001 at 07:42 UTC

    You could, of course, put the lexical variables into the symbol table. Exporter doesn't do this, and I'm still even mostly sure that it's better that way.

    Some code (and it demonstrates how import() works, too):

    In test.pl:

    use MyTest; print "Once-lexical variable holds $lexvar\n";

    In MyTest.pm:

    package MyTest; my $lexvar = 7; # This function is called automatically whenever # anyone 'use's (or 'require's, I'm pretty sure) # our module. Note that this happens at COMPILE TIME. sub import { # symbol table manipulation usually requires # the use of symbolic references... no strict 'refs'; # Figure out where to export to. # Check `perldoc -f caller` for info on caller. my $pkg_to_export_to = (caller)[0]; # Make the scalar part of the entry in the symbol # table of the calling package for 'lexvar' into a hard # reference to our lexical variable. This is called # typeglob aliasing. *{$pkg_to_export_to . '::lexvar'} = \$lexvar; }

    Okay, maybe I'm just sick. ;-)

    bbfu
    Seasons don't fear The Reaper.
    Nor do the wind, the sun, and the rain.
    We can be like they are.

      FYI, Exporter can't do that since its code is in a different file and therefore has no access to the lexical variables in your module's file.

              - tye (but my friends call me "Tye")

        I know that. :-P

        What I was thinking of, though I didn't actually say it, was some sort of mechanism where you would pass it a reference to a lexical variable that it would then export into the caller's symbol table. I can't think of any reason that would be useful (and it kinda defeats the whole point of having package lexicals, anyway) except as an insane way of (not) avoiding the use vars syntax. :-)

        use strict; my $family; my @jewels; use base qw(Exporter); use vars qw(@EXPORT @EXPORT_LEXICALS); @EXPORT = qw( foo bar $blah ); @EXPORT_LEXICALS = ( \$family, \@jewels );

        Man, that's just sick. ;-p

        bbfu
        Seasons don't fear The Reaper.
        Nor do the wind, the sun, and the rain.
        We can be like they are.