簡體   English   中英

如何防止在Perl中覆蓋子?

[英]How can I prevent a sub being overwritten in Perl?

我正在使用遺留代碼,並且require一個定義子foo的.pl文件。 我的問題是在我的main:: namespace中已經存在另一個子foo ,稍后在我目前沒有處理的程序的一部分中調用它。

我需要的文件定義了sub foo {}因為很明顯它不希望foo在通常被調用的地方發生。 就我而言,這很糟糕。

我試過玩*foo glob:

*old_foo = *foo;
require 'foo_killer.pl';
*foo = *old_foo;

當然,這不起作用,因為我只創建了一個別名(正如brian d foy在Mastering Perl的第133頁指出的那樣)因此*old_foo將指向現在的'empty'子程序。

有沒有辦法以某種方式將*foo{CODE}中的內容復制到其他地方而不是別名呢? 或者是否有其他方法可以解決這個問題?

自己搞清楚了。 我必須使用typeglob的CODE部分,而不是將整個typeglob分配給另一個typeglob。 這樣它似乎制作副本。

*old_foo = *foo{CODE};
require 'foo_killer.pl';
*foo = *old_foo{CODE};

brian d foy也在Mastering Perl中討論過這個問題(第131頁),但沒有提到復制部分。

試試這樣吧

{
    local *foo;
    require 'foo_killer.pl';
}

我建議一勞永逸地將邪惡的遺留代碼包裝到一個包中。

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" !)

這樣你可以決定是否通過use Foo qw(foo);加載foo use Foo qw(foo); use Foo qw(bar);

更新:哦,你最好計算相對於__FILE__ foo_killer.pl路徑,而不是通過絕對路徑加載它:

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;

這取決於你(和你的團隊)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM