I have a subroutine, csay
, that's defined in a Perl class (package). There are several subclasses of it that run that subroutine often and throughout themselves. Its behaviour depends on a few variables (most of which must be given as arguments), one of which is constant within any lexical scope ($debug_level
). I'm trying to avoid duplicating code as much as possible, including having to pass the "constant" variable as an argument every single time or prefixing every usage with $self->
.
I'm not against using compile-time substitution (if such a thing exists in Perl), but I'd like to avoid using instances (bless
ing hashes, etc) if possible. See below for an example of what I'm trying to do. Any ideas?
package SystemManager::Action::Generic;
sub csay($self, $cur_debug_level, $min_debug_level, $message) {
if ($cur_debug_level >= $min_debug_level) { print("$message\n"); }
}
sub prepare_system($self)...
package SystemManager::Action::Backup;
use parent "SystemManager::Action::Generic";
sub backup_system($self,$debug_level,@files) {
$self->csay($debug_level, 1, "Starting backup");
$self->prepare_system();
$self->csay($debug_level, 1, "Iterating through files");
for my $file in (@files) {
$self->csay($debug_level, 2, "Processing $file");
...
}
...
}
csay
doesn't need to be part of the same class; the most important part is to not have to specify $debug_level
as an argument every single time.
As an alternative to the answer by Håkon Hægland, you could use an exportable our
variable:
package SystemManager::Action::Generic;
our $cur_debug_level = 0;
our @EXPORT = qw($cur_debug_level); # or @EXPORT_OK to export explicitly only
sub csay($self, $min_debug_level, $message) {
if ($cur_debug_level >= $min_debug_level) { print("$message\n"); }
}
package SystemManager::Action::Backup;
use parent "SystemManager::Action::Generic";
sub backup_system($self,@files) {
$self->csay(1, "Starting backup");
$self->prepare_system();
$self->csay(1, "Iterating through files");
for my $file in (@files) {
$self->csay(2, "Processing $file");
...
}
...
}
package main;
use SystemManager::Action::Backup;
$cur_debug_level = 2;
my $backup = Backup->new();
$backup->backup_system(<*.txt>);