2012-07-03 46 views
0

我已經在我的程序不管三七二十一期運用.pm的文件並沒有真正進入使用包,除非真正需要的。從本質上說,我只想有共同的套路在的.pm和use'd時,他們將成爲主要部分(名.pm就沒有包裝或出口商或類似的...只是一堆例程)。使用無包裝 - 大亂?

不過,我遇到的情況來了一天,我想我知道發生了什麼,爲什麼,但我希望從專家那裏獲得一些教練位置上的最佳實踐,以及如何解決這個問題。從本質上說,應該總是使用包嗎?當我只想將普通例程吸收到main(或父模塊/包)中時,是否應該「執行」文件?出口商是否真的能夠處理所有這些問題?

這裏是什麼,我遇到了(我不會發布的原代碼,因爲它是千行......這只是問題的本質)的示例代碼。

Pgm1.pl:

use PM1; 
use PM2; 
print "main\n"; 
&pm2sub1; 
&pm1sub1; 

PM1.pm:

package PM1; 
require Exporter; 
@ISA=qw(Exporter); 
@EXPORT=qw(pm1sub1); 
use Data::Dump 'dump'; 
use PM2; 
&pm2sub1; 
sub pm1sub1 { 
    print "pm1sub1 from caller ",dump(caller()),"\n"; 
    &pm2sub1; 
} 
1; 

PM2.pm:

use Data::Dump 'dump'; 
sub pm2sub1 { 
    print "pm2sub1 from caller ",dump(caller()),"\n"; 
} 
1; 

從本質上說,我一直use'ing PM2.pm一段時間後,其& pm2sub1子例程。然後我在某個時候寫了PM1.pm,它也需要PM2.pm的例程。然而,像這樣做,PM2.pm的模塊被吸收到PM2.pm的包中,然後Pgm1.pl無法做到這一點,因爲PM2.pm已經被使用了。

該代碼會產生

Undefined subroutine &main::pm2sub1 called at E:\Scripts\PackageFun\Pgm1.pl line 4. 
pm2sub1 from caller ("PM1", "PM1.pm", 7) 
main 

然而,當我換用的語句,像這樣在Pgm1.pl

use PM2; 
use PM1; 
print "main\n"; 
&pm2sub1; 
&pm1sub1; 

... Perl的將允許PM2.pm的模塊爲主力,但然後不進PM1.pm的包:

Undefined subroutine &PM1::pm2sub1 called at PM1.pm line 7. 
Compilation failed in require at E:\Scripts\PackageFun\Pgm1.pl line 2. 
BEGIN failed--compilation aborted at E:\Scripts\PackageFun\Pgm1.pl line 2. 

所以,我想我可以解決這個問題,通過獲得宗教信封和E xporter在我所有的模塊中。麻煩的是,PM2.pm已經在很多其他程序中使用過,所以這將是大量的迴歸測試,以確保我沒有破壞任何東西。

想法?

+0

所以你的具體問題是;當您在主腳本中更改'use'語句的順序時,PM2是否無法正確加載到PM1的命名空間中? – Flimzy

+0

如果不使用軟件包,例程將首先被使用。這意味着其他軟件包必須知道例程下落的位置並相應地訪問它們。我會認爲,使用沒有包的模塊會將這些例程放入所有使用它們的包中。也許使用「做」是這個答案? – mswanberg

回答

3

use不會加載相同的文件不止一次。但是,它會每次調用目標程序包的import。你應該將你的PM2格式化爲適當的包,因此use可以找到它的import並從那裏將請求者的名字空間導出到函數中。

(或者你可以通過完全限定它的名字偷偷你的導入功能到合適的包,但不這樣做。)

+0

哦,我沒有意識到OP不明白'require'只加載一次。這就是爲什麼''應該在這裏使用。 – ikegami

0

你找麻煩安排您這樣的代碼。給每個模塊一個包名稱(命名空間),然後完全限定對其功能的調用,例如, PM2::sub1()致電sub1PM2。您已經在命名帶有軟件包名稱的功能(pm2sub1);它是兩個額外字符(::)以正確的方式執行,然後您不需要打擾出口商。

+0

我從來不喜歡::東西...使代碼更不可讀,國際海事組織。如果一個模塊或腳本需要一個例程,它應該擁有它。 – mswanberg

+1

我不明白如何使用假名稱空間比真實名稱空間更具可讀性。後者更清晰。 –