I'm writing a basic program whose core logic is split across several project-specific modules for cleanliness (keeping subroutines organised by their purpose in the program's logic).
Suddenly had trouble exposing an option from the main
package in one of the modules, and using the our
statement appeared to have no effect.
For brevity, I'll copy+paste an isolated test case I wrote to examine this behaviour:
#!/usr/bin/perl
use warnings;
use strict;
use File::Basename;
# The variable to be read by the module.
our $verbose = 1;
# Load Output.pm from directory
use lib dirname "$0";
use Output;
write_message "Hello, world\n";
package Output;
use warnings;
use strict;
use parent "Exporter";
our @EXPORT = qw(write_message);
# Should be imported?
our $verbose;
sub write_message {
print $_[0] unless !$verbose;
}
1;
Expected result: "Hello, world"
Actual result: Dead silence
It's quite possible that what I'm trying to achieve isn't even possible in Perl, as this isn't the intended use of modules (and heck, I understand why that'd be the case).
I'm still quite new to Perl and there are some things I'm struggling to wrap my head around. I've seen people recommend using the our
declarator to expose a variable across packages, but I can't understand why this isn't working.
PS: If anybody knows a better approach to splitting an app's program-specific logic between modules, I'd appreciate some pointers too. :) But first and foremost, I'd prefer to learn why our
-ing a variable isn't working.
An our
statement just creates a package variable (whereas my
creates a lexical variable). It has nothing to do with exporting
The best option is probably to declare the variable in the Output
package and access it as $Output::verbose
elsewhere. Like this
#!/usr/bin/perl
use strict;
use warnings;
use File::Basename;
use lib dirname $0;
use Output;
$Output::verbose = 1;
write_message "Hello, world\n";
package Output;
use strict;
use warnings;
use Exporter 5.57 'import';
our @EXPORT = qw/ write_message /;
our $verbose;
sub write_message {
print $_[0] if $verbose;
}
1;
Note that I have also removed the incorrect quotes from around $0
, and ever since version 5.57 of Exporter
it has been possible (and preferable) to import it's import
subroutine instead of subclassing it