Reputation: 54373
I'm working with legacy code and have to require
a .pl file that defines a sub foo
. My problem is that in my main::
namespace there already is another sub foo
, which is called later in a part of the program I'm currently not dealing with.
The file I require defines sub foo {}
because obviously it does not want the foo things to happen where it is usually called. In my case, that is bad.
I've tried playing around with the *foo
glob:
*old_foo = *foo;
require 'foo_killer.pl';
*foo = *old_foo;
Of course, that doesn't work since I've only created an alias (as brian d foy points out on page 133 of Mastering Perl) and thus *old_foo
will point to the now 'empty' subroutine.
Is there a way to somehow copy what's in *foo{CODE}
to somewhere else instead of aliasing it? Or is there maybe another approach to solve this?
Upvotes: 5
Views: 142
Reputation: 5318
I would suggest wrapping the evil legacy code into a package once and for all.
package Foo;
use strict;
use warnings;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(foo bar $evil $global $variables);
do "foo_killer.pl"
or die "Failed to load foo_killer.pl: ".($@ || $!);
1;
Here I use do
, because require
does nothing if the code is required elsewhere. (We had ugly require "//path/to/code.pl"
because of this!)
This way you can decide whether to load foo
via use Foo qw(foo);
or use Foo qw(bar);
.
UPDATE: Oh, and you'd better calculate path to foo_killer.pl
relatively to __FILE__
and not load it by absolute path:
my $foo_killer = __FILE__; # $LIB/Foo.pm
$foo_killer =~ s,(/+[^/]+),legacy,; # $LIB/legacy
$foo_killer .= "foo_killer.pl"; # $LIB/legacy/foo_killer.pl
# now do $foo_killer;
It's up to you (and your team) though.
Upvotes: 2
Reputation: 54373
Figured it out myself. I have to use the CODE
portion of the typeglob instead of assigning the whole typeglob to another typeglob. That way it seems to make a copy.
*old_foo = *foo{CODE};
require 'foo_killer.pl';
*foo = *old_foo{CODE};
brian d foy also talks about this in Mastering Perl (on page 131f), but doesn't mention the copying part.
Upvotes: 4