2012-08-30 57 views
1

我偶爾會遇到這個問題。出於某種原因,當我嘗試調用導出的子程序時,出現「Undefined subroutine」錯誤,我不知道爲什麼,因爲它似乎是在成熟代碼中出現藍色。未找到導出的Perl子文件

發生的最後一次我想我使用了諸如「package_2 :: exported_sub()」之類的東西。「這次工作,但它只是返回package_2中的另一個子錯誤。即使把「使用package_2」在上面的行並沒有幫助!我能想到的唯一的事情就是導出的子程序在某種程度上是未定義的。

我的代碼看起來有點像這樣:

文件package_1.pm:

package package_1; 

require Exporter; 
@ISA = qw(Exporter); 

@EXPORT = qw(
local_sub 
); 

use package_2; 
use strict; 
use warnings; 
use diagnostics; 

sub local_sub { 
    &exported_sub; 
} 

文件package_2.pm:

package package_2; 

require Exporter; 
@ISA = qw(Exporter); 

@EXPORT = qw(
exported_sub 
); 

use strict; 
use warnings; 
use diagnostics; 

sub exported_sub { 
# do something 
} 

我在我束手無策。 ..當我彈出一個無關的熱門票時,我正在製作一個無關的熱門票,明天就會開始用戶測試!

在此先感謝!


更新:

池上,感謝您的修復!不過,我很好奇。我再次遇到這個問題,但是這次我從來沒有找到循環依賴。我把它縮小到一行:

$row->{$attr} = ' ' unless ($row->{$attr}); 

很顯然,這條線與使用或根本無關!我查看了Apache日誌,但似乎沒有什麼突出的,但將解決任何我找到的工作。我還會看看我能否獲得更多警告。

除此之外,您作爲下一步推薦什麼?

謝謝!

+0

我忘了提及警告和診斷程序沒有返回任何內容......我剛收到錯誤消息。 – ThorInSuburbia

+2

您發佈的代碼對我來說很好用(使用簡單的主程序'use strist; use package_1; local_sub();',因此您應該嘗試找出示例代碼中缺少的內容以使其失敗。 –

+2

這個問題似乎是由第一個'使用'的第三個文件。註釋'use'行解決了這個問題,所以我想知道是否有什麼奇怪的文件,如DOS CR,我會繼續挖掘! – ThorInSuburbia

回答

4

我懷疑你有循環依賴:package_1使用package_2和package_2使用package1(直接或間接)。

下面是我最初發表在PerlMonks一個解決方案:http://www.perlmonks.org/?node_id=778639


[使用這種技術需要的是在您的系統存在設計缺陷的一個很重要指標,但我認識到資源並非總能解決設計缺陷。 ]

如果ModA使用ModB,ModB使用ModA,並且ModA或ModB從另一個引入符號,則需要注意代碼執行順序。我發現避免問題的最好方法是在加載任何其他模塊之前設置Exporter。

ModA.pm

package ModA; 

use strict; 
use warnings; 

BEGIN { 
    our @ISA = qw(Exporter); 
    our @EXPORT_OK = qw(...); 
    require Exporter; 
} 

use This; 
use ModB; 
use That; 

... 

1; 

ModB.pm

package ModB; 

use strict; 
use warnings; 

BEGIN { 
    our @ISA = qw(Exporter); 
    our @EXPORT_OK = qw(...); 
    require Exporter; 
} 

use This; 
use ModA; 
use That; 

... 

1; 
+0

謝謝!我會試試。 – ThorInSuburbia

+0

這個工作,我很抱歉,我還沒有回到你確認。不幸的是,這是一個內部網頁我接管了200多個文件,還有幾個使用了相同的實用程序文件,這會降低我的性能,還是可以忽略不計? – ThorInSuburbia

+0

性能將得到很大提高,因爲在代碼不執行orm之前。 – ikegami

1

你確定你的use系列完全類似於use package_2 qw(xyz);之類的東西嗎?

後者將定義Exporter的import()子程序將導出到調用者模塊中的內容。

+1

是的,使用線是非常基本的。 – ThorInSuburbia

0

希望我的經驗能適合你的情況。 Perl程序包名稱必須填寫名稱空間。 如果你的模塊文件是在路徑$ PERL_LIB /水果/ Apple.pm 然後在模塊文件,必須指定命名空間水果::

package Fruit::Apple; 

....... 

如果你只寫

package Apple; 

....... 

沒有編譯錯誤。但是當你在模塊文件Apple.pm中調用你的方法時,會得到'Undefined subroutine'錯誤。