我正在使用遗留代码,并且必须require
定义子foo
的.pl文件。我的问题是在我的main::
命名空间中已经存在另一个子foo
,稍后在我目前没有处理的程序的一部分中调用它。
我需要的文件定义sub foo {}
,因为很明显它不希望foo在通常被调用的地方发生。就我而言,这很糟糕。
我试过玩*foo
glob:
*old_foo = *foo;
require 'foo_killer.pl';
*foo = *old_foo;
当然,这不起作用,因为我只创建了一个别名(正如brian d foy指出掌握Perl 的第133页),因此*old_foo
将指向现在是'空'子程序。
有没有办法以某种方式将*foo{CODE}
中的内容复制到其他地方而不是别名呢?或者可能有另一种解决方法吗?
答案 0 :(得分:3)
自己想出来。我必须使用typeglob的CODE
部分,而不是将整个typeglob分配给另一个typeglob。这样它似乎可以复制。
*old_foo = *foo{CODE};
require 'foo_killer.pl';
*foo = *old_foo{CODE};
brian d foy也在 Mastering Perl (第131页)中讨论了这个问题,但未提及复制部分。
答案 1 :(得分:3)
试试这个
{
local *foo;
require 'foo_killer.pl';
}
答案 2 :(得分:2)
我建议一劳永逸地将邪恶的遗留代码包装到一个包中。
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;
我在这里使用do
,因为require
如果其他地方需要代码则不会执行任何操作。 (因为这个,我们有丑陋的require "//path/to/code.pl"
!)
这样您就可以决定是通过foo
还是use Foo qw(foo);
加载use Foo qw(bar);
。
更新哦,您最好计算foo_killer.pl
相对于__FILE__
的路径,而不是按绝对路径加载:
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;
这取决于你(和你的团队)。