so, i have a program like this:
#!/usr/bin/perl -w
use strict;
foreach (@data) {
if($_ eq "foo") {
use Foo;
process();
}
if($_ eq "bar") {
use Bar;
process();
}
...
}
Each included module is somewhat similar, the only difference being what the process()-sub does.
#!/usr/bin/perl -w
use strict;
sub process {
...
}
My issue: the input for the main script is a (possibly long) list of things, while processing that list i get continuous "Subroutine redefined" errors (obviously). Is there any way to "un-use" a module?
Due to the fact that the library of possible "actions" to include may grow in the future, i thought this way of including modules dynamically would be the best approach. Many thanks for your help :)
As @pilcrow said, you can solve this issue quickly by using require
instead of use
, but, I think this is a good example where Polymorphism is to be used.
You can create a base class like:
package Processors::Base;
sub new{
my $class = shift;
return bless {}, $class;
}
sub process{
die "You can only use a subclass of me";
}
1;
And then, create your processors as packages that inherit from this base package.
package Processors::Foo;
sub process{
... do stuff ...
}
1;
Then your code could look like:
#!/usr/bin/perl -w
use strict;
for my $pkg (@data) {
(my $path = $pkg) =~ s{::}{/}g;
require "$path.pm";
$pkg->process;
...
}
Of course, the modifications assume that $_
is in the form of Processors::Foo
for example. Even if you can not modify the content of your @data
, I think you can generate the name of the processor so that you are able to invoke its process()
method.
If you want to be a show-off, you could create a Factory
object that will return instances of your processors based on the value of $_
:
package Processors::Factory;
sub get_instance{
my ($self, $processor_name) = @_;
my $full_processor_name = sprintf('Processors::%s', ucfirst($processor_name) );
(my $full_processor_path = $full_processor_pkg) =~ s{::}{/}g;
require "$full_processor_path.pm";
my $processor = $full_processor_name->new();
return $processor;
}
1;
Then, your code would look like:
#!/usr/bin/perl -w
use strict;
use Processors::Factory;
foreach (@data) {
Processors::Factory->get_instance( $_ )->process();
...
}