2009-09-20 89 views
0

我有一個模塊Routines.pm:爲什麼我的Perl程序會抱怨需要顯式包名?

package Routines; 
use strict; 
use Exporter; 

sub load_shortest_path_matrices { 
    my %predecessor_matrix = shift; 
    my %shortestpath_matrix = shift; 
    ... 
} 

從另一個腳本我所說的子模塊中,通過在其中恰好有相同的名稱參數:

use Routines; 
use strict; 

my %predecessor_matrix =(); 
my %shortestpath_matrix =(); 
&Routines::load_shortest_path_matrices($predecessor_matrix, $shortestpath_matrix); 

然而,這不編譯,我得到

全局符號「$ predecessor_matrix」需要明確的包名

類型的錯誤。在Perl中不可能像這樣在不同的範圍中給變量賦予相同的名稱? (我來自C背景)

+3

鄒所知,Perl是比C不同,儘管在關鍵字誤導性相似之處。我的建議是去購買和閱讀「學習Perl」來學習Perl「認爲」的方式。 – lexu 2009-09-20 17:17:19

+0

「使用診斷」;將有助於 – 2009-09-21 11:35:15

回答

14

$predecessor_matrix是標量和%predecessor_matrix是一個散列。 Perl中的不同類型(標量,數組,哈希,函數和文件句柄)在符號表中具有不同的條目,因此可以具有相同的名稱。

此外,你的功能有問題。它希望能夠從@_中獲得兩個哈希值,但列表上下文中的哈希值(例如函數的參數列表)會生成一個鍵值對列表。因此,%predecessor_matrix%shortestpath_matrix都將在函數的%predecessor_matrix中結束。你需要在這裏做的是使用references

package Routines; 
use strict; 
use Exporter; 

sub load_shortest_path_matrices { 
    my $predecessor_matrix = shift; 
    my $shortestpath_matrix = shift; 
    $predecessor_matrix->{key} = "value"; 
    ... 
} 

use Routines; 
use strict; 

my %predecessor_matrix; 
my %shortestpath_matrix; 
Routines::load_shortest_path_matrices(
    \%predecessor_matrix, 
    \%shortestpath_matrix 
); 

然而,在經過結構加載作爲參數更類似於C比Perl-等。 Perl可以返回多個值,所以它更經常可以看到這樣的代碼:

package Routines; 
use strict; 
use Exporter; 

sub load_shortest_path_matrices { 
    my %predecessor_matrix; 
    my %shortestpath_matrix; 
    ... 
    return \%predecessor_matrix, \%shortestpath_matrix; 
} 

use Routines; 
use strict; 

my ($predecessor_matrix, $shortestpath_matrix) = 
    Routines::load_shortest_path_matrices(); 

for my $key (keys %$predecessor_matrix) { 
    print "$key => $predecessor_matrix->{$key}\n"; 
} 
5

您正在聲明散列%predecessor_matrix,但正試圖傳遞標量$ predecessor_matrix。散列存在,標量不存在。

也許你想傳遞引用哈希?例程:load_shortest_path_matrices(\%predecessor_matrix,\%shortestpath_matrix);


這裏是另一種方式來編寫它:

use strict; 
use warnings; 
use Routines; 

my $predecessor_matrix = {}; 
my $shortestpath_matrix ={}; 
Routines::load_shortest_path_matrices( $predecessor_matrix 
             , $shortestpath_matrix 
            ); 

package Routines; 
use strict; 
use Exporter; 

sub load_shortest_path_matrices { 
    my $predecessor_matrix = shift; 
    my $shortestpath_matrix = shift; 
    ... 
} 

您可以訪問散列的內容是這樣

my $foobar=$shortestpath_matrix->{FOOBAR}; 
+6

溝渠&,在這種情況下是不必要的,並可能導致其他問題。除非你知道它是什麼以及爲什麼要使用它,否則不要使用&前綴來調用函數。 – 2009-09-20 17:17:21

+0

謝謝,你是對的,我錯過了剪切和粘貼Suan的代碼。 – lexu 2009-09-20 17:28:35

+0

@Chas。歐文斯 - 求求不同;只要你還使用(),即使沒有參數,也不會有錯(有時候是正確的)。 – ysth 2009-09-21 04:55:12

相關問題