Reputation: 583
I am forced to use old version of Apache2::Cookie class which contains bug in method fetch(). I tried to override method in startup script, but it doesn't work later in other modules than startup script:
local *Apache2::Cookie::fetch = sub { ... }
How to override method globally for all other modules?
Upvotes: 1
Views: 376
Reputation: 54333
As Sobrique pointed out in their comment, the local
is definitely an issue. But not the only one.
You need to load the pacakge first before you do this. Perl will take the last definition of the sub, just like the last assigned value will be the value of a variable.
my $foo;
$foo = 1;
$foo = 3;
print $foo; # 3, obviously
The same goes for your overwriting.
*Apache2::Cookie::fetch = sub { ... }; # note ... is valid syntax
require 'foo';
$cookie = Apache2::Cookie->new; # not sure if that is correct
# in foo.pm
use Apache2::Cokie; # this will overwrite your implementation
Loading modules in Perl works with %INC
, a super-global hash that keeps track of which files have been loaded. If you use
a file twice, it only gets loaded and parsed the first time. The second time, it will only call import
on the package.
So the trick is to load Apache2::Cookie first, so it's already parsed when the real code loads it again.
use Apache2::Cookie;
BEGIN {
*Apache2::Cookie::fetch = sub { ... };
}
require 'foo'; # or use, no matter
$cookie = Apache2::Cookie->new; # not sure if that is correct
# in foo.pm
use Apache2::Cokie; # now this won't overwrite your implementation
Now Perl already has the file loaded, and the package installed in its guts. Then you overwrite the sub. Then it gets not loaded again and your fix is still intact when it gets called.
Upvotes: 4