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

Is it possible to catch when a reference is made to an undefined variable in another module.

For instance, in the following example, I'd like to raise an error when $a::z is accessed.

Preferably I'd like to know at compile time, but run time would be fine. Is there a way to do this?

package a; our $x = 1; package main; print "a::x = ", $a::x, "\n"; # Fine print "a::z = ", $a::z, "\n"; # want to raise error here

Replies are listed 'Best First'.
Re: Catch references to undefined variables in other modules? (export)
by tye (Sage) on Oct 29, 2007 at 21:50 UTC

    The best practice is:

    use a qw( $x $z );

    which produces, at compile time (for a properly written a.pm):

    "$z" is not exported by the a module Can't continue after import errors at -e line 1

    Here is the example a.pm I used:

    package a; require Exporter; *import= \&Exporter::import; our @EXPORT_OK= qw( $x ); our $x= 'x'; 1;

    - tye        

      Do you have any suggestions other than Export if I've got about 800 constants defined in my 'Constants.pm' module and 400 modules which use them? Each module is only importing the constants it needs, but I still would like to avoid creating all those extra symbol table entries and still catch misspelled names at compile time.
        Each module is only importing the constants it needs, but I still would like to avoid creating all those extra symbol table entries

        If each module is only importing a few, then you are only creating a few extra symbol table entries. So I don't see what you are optimizing here. It isn't like symbol table entries take a huge amount of space. A few more per module isn't going to be much compared to the size of the module.

        - tye        

Re: Catch references to undefined variables in other modules?
by jettero (Monsignor) on Oct 29, 2007 at 17:17 UTC

    I have looked for this before also. It kinda irks me that you can make up variables in other name spaces even under use strict... I'm not aware of any solution though.

    use strict; use warnings; $shouldnt::work::imo = "It does work.. *sigh*"; print "$shouldnt::work::imo\n";

    So if anyone has a way to make my example fail to work, I'd like to know it. In fact, this may be the exact same question (with a different example).

    -Paul

Re: Catch references to undefined variables in other modules?
by toolic (Bishop) on Oct 29, 2007 at 17:05 UTC
    When I add use warnings; to your code like this:
    #!/usr/bin/env perl use warnings; use strict; package a; our $x = 1; package main; print "a::x = ", $a::x, "\n"; # Fine print "a::z = ", $a::z, "\n"; # want to raise error here
    I get the following warning messages:
    Name "a::z" used only once: possible typo at ./647879.pl line 13. a::x = 1 Use of uninitialized value in print at ./647879.pl line 13. a::z =
    Is this what you are looking for?
      Not exactly, because the first warning won't show up if I happen to reference $a::z twice.

      The "use of uninitialized value" message is nice, but it's not telling me that $a::z was the cause of the problem.

      Basically I want to catch when the programmer mis-spelled a variable name, i.e. typed $a::z when they meant $a::x.

      The names in package a will be special in that they will only be defined within package a's lexical scope.