我正在開發一個應用程序,它必須逐塊替換現有的意大利麪條代碼。爲了達到這個目的,我有一個調度器,它在URI匹配時運行所需的HTTP資源,否則使用傳統的HTTP資源類。有沒有辦法在Perl中模擬內置的require函數?
因此,這個傳統的HTTP資源必須require
舊系統的入口點文件,我想弄清楚如何測試這個過程。我現在看到的方式是我想用模擬子程序替換原始的require
函數,並檢查它是否已用適當的文件名稱進行調用。
這是可能的,如果沒有,也許有更好的方法來做到這一點?
我正在開發一個應用程序,它必須逐塊替換現有的意大利麪條代碼。爲了達到這個目的,我有一個調度器,它在URI匹配時運行所需的HTTP資源,否則使用傳統的HTTP資源類。有沒有辦法在Perl中模擬內置的require函數?
因此,這個傳統的HTTP資源必須require
舊系統的入口點文件,我想弄清楚如何測試這個過程。我現在看到的方式是我想用模擬子程序替換原始的require
函數,並檢查它是否已用適當的文件名稱進行調用。
這是可能的,如果沒有,也許有更好的方法來做到這一點?
一種更好的方式來覆蓋require
全局可在中安裝掛鉤3210。這個鮮爲人知的功能在the require
documentation的末尾進行了描述。
這裏有一個簡單的例子,用於攔截模塊名稱以HTTP的任何請求:
BEGIN {
unshift @INC, sub {
my ($self, $file) = @_;
return unless $file =~ /^HTTP/;
print "Creating mock $file\n";
my @code = "1"; # Fake module must return true
return sub { $_ = shift @code; defined $_ };
}
}
require HTTP::Foo;
use HTTPBar;
注意,因爲它是基於require
,這也嘲笑use
。
要在單個封裝覆蓋require
:
use subs 'require'; # imports `require` so it can be overridden
sub require {print "mock require: @_\n"}
要覆蓋require
全局:
BEGIN {
*CORE::GLOBAL::require = sub {print "mock require: @_\n"}
}
然後:
require xyz; # mock require: xyz.pm
require Some::Module; # mock require: Some/Module.pm
你需要注意的其他一些東西。這要麼補充或取代覆蓋require
的需要。
您是否知道您可以在您的@INC
路徑中添加鉤子作爲代碼參考?這些將在全球範圍內適用於use
和require
報表。
引用的perldoc require
您也可以通過將Perl代碼直接到@INC數組插入掛鉤插入導入工具。
有三種形式的鉤子:子程序引用,數組引用和祝福對象。
子程序引用是最簡單的情況。當包含系統遍歷@INC並遇到一個子例程時,這個子例程會被調用兩個參數,第一個是對自身的引用,第二個是要包含的文件名(例如「Foo/Bar.pm」) 。該子程序應該按照下面的順序返回任何內容或者最多三個值的列表:
1.一個文件句柄,從中讀取文件。
2.對子程序的引用。如果沒有文件句柄(前一個項目),那麼這個子程序應該爲每個調用產生一行源代碼,將行寫入$ _並返回1,最後在文件結尾返回0。如果存在文件句柄,則將調用該子例程以充當簡單源過濾器,其中該行在$ _中讀取。再次,每個有效行返回1,所有行返回後返回0。
3.子程序的可選狀態。狀態以$ _ [1]的形式傳入。在子程序自身的引用傳入爲$ _ [0]
下面是一個例子:
#!/usr/bin/perl
sub my_inc_hook {
my ($sub_ref, $file) = @_;
unless ($file =~ m{^HTTP/}) {
warn "passing through: $file\n";
return;
}
warn "grokking: $file\n";
return (\*DATA);
}
BEGIN {
unshift(@INC, \&my_inc_hook);
}
use strict;
require warnings;
require HTTP::Bazinga;
HTTP::Bazinga::it_works();
__DATA__
package HTTP::Bazinga;
sub it_works {warn "bazinga!\n"};
1;
產地:
$ perl inc.pl
passing through: strict.pm
passing through: warnings.pm
grokking: HTTP/Bazinga.pm
bazinga!
我相信這個工程的Perl 5.10.0以上。
它也適用於5.8。 – cjm
感謝您的延伸解釋,我已經接受了類似的答案,我相信這是第一個發佈。 –
難道這不會模擬只有該模塊的「需要」功能嗎?我也需要它爲所有其他模塊嘲笑。 –
是的,請參閱全局版本的更新。 –
謝謝,它的工作原理,但我決定使用鉤子。 –