Search code examples
perlpackagescoping

Perl package variables without using our


Is it possible to set a package variable without using our.

Here's a code sample that would explain the case better than words:

package A::B::C;

use strict;
use warnings;
use Exporter ();
our @ISA = qw/Exporter/;
our @EXPORT = ();
our @EXPORT_OK = qw/INFO/;
our %EXPORT_TAGS = (
    default => [qw/INFO/]
);
Exporter::export_ok_tags("default");

BEGIN {
    $C::verbose = 0;
}

sub INFO {
    my $msg = shift;

    if ($C::verbose) {
        print("$msg\n");
    }
}

Setting the variable $verbose from a script that uses package A::B::C does not change the value of $verbose in the package:

use A::B::C;

$A::B::C::verbose = 1;

I perfectly know that using 'our' in the package would solve the issue, but I'm more interested to know what's happening and why it's not possible to set the variable $verbose from a script that uses package A::B::C. Or even better, what happens to package variables that are only used (and not formally declared) in package subroutines; what scope do they get?


Solution

  • You need to reference the correct package name: $verbose does not reside in package C but in A::B::C. So the following works as expected:

    BEGIN {
        $A::B::C::verbose = 0; # Changed
    }
    
    sub INFO {
        my $msg = shift;
    
        if ($A::B::C::verbose) { # Changed
            print("$msg\n");
        }
    }