2012-12-20 27 views
5

我在perl子程序定義中聲明數組類型參數時遇到了編譯錯誤。 我的完整代碼如下:如何將數組和散列數據類型傳遞給perl中的子例程參數?

use Data::Dumper; 
use Win32; 
use Win32::Service; 
use strict; 
use warnings; 
my @Services = qw(NNMAction RpcEptMapper smstsmgr SNMPTRAP); 
my $server = 'nnmi.hclt.corp.hcl.in'; 
ServiceStatus($server , @Services); 

sub ServiceStatus ($serverName,@serverServices) 
{  my %statcodeHash = ( '1' => 'stopped', 
          '2' => 'start pending', 
          '3' => 'stop pending', 
          '4' => 'running', 
          '5' => 'continue pending', 
          '6' => 'pause pending', 
          '7' => 'paused'   ); 

    foreach my $serv (@serverServices) 
    {  my %status; 
    my $ret = Win32::Service::GetStatus($serverName , $serv , \%status); 
    if ($ret) 
    {  print "success \t$statcodeHash{$status{CurrentState}} \t$serv\n"; 
    } 
    else 
    {  print Win32::FormatMessage(Win32::GetLastError()), "\n"; 
    } 
    } 
} 

編譯錯誤

>perl -w perl_RemoteServiceStatus.pl 
Prototype after '@' for main::ServiceStatus : $serverName,@serverServices at per 
l_RemoteServiceStatus.pl line 21. 
Illegal character in prototype for main::ServiceStatus : $serverName,@serverServ 
ices at perl_RemoteServiceStatus.pl line 21. 
main::ServiceStatus() called too early to check prototype at perl_RemoteServiceS 
tatus.pl line 16. 
Global symbol "@serverServices" requires explicit package name at perl_RemoteSer 
viceStatus.pl line 31. 
Global symbol "$serverName" requires explicit package name at perl_RemoteService 
Status.pl line 33. 
Execution of perl_RemoteServiceStatus.pl aborted due to compilation errors. 

請幫我調試的部份代碼。我相信這對一些人來說是一塊蛋糕。

+3

perl沒有聲明參數類型的機制。原型看起來就像他們乍一看那樣,但事實上它們有着完全不同的目的;你不應該使用它們。 – ysth

回答

4
sub ServiceStatus 
{ 
    my ($serverName,@serverServices) = @_; # Declare variables and populate from @_, the parameter list. 
    ... 

} 
+0

感謝RobEarl爲您提供寶貴的答案 –

+0

這篇評論對我來說很有幫助(在2015年),在PHP和JavaScript中工作了一年多,並且在Perl中忘記了使用subs的@_上下文。謝謝 –

6

Perl原型不是命名參數,或者甚至不給它們的類型,它們用於創建評估上下文。您需要修改的子程序是這樣的:

sub ServiceStatus ([email protected]){ 
    my ($serverName,@serverServices) = @_; 
    # ... 
} 

或完全擺脫原型:

sub ServiceStatus { 
    my ($serverName,@serverServices) = @_; 
    # ... 
} 
+0

優秀的超現實。得到您的消息響亮而清晰:)謝謝 –

9

這是非常簡單的:不要使用prototypes,如果你不知道他們是如何工作的。爲了讓您的代碼運行,子程序聲明從改變:

sub ServiceStatus ($serverName,@serverServices) 
{ #... 

到:

sub ServiceStatus { 
    my ($serverName, @serverServices) = @_; 

編輯:如果您需要傳遞多個陣列/散列子程序,或數組/哈希應該在其他值之前通過,您必須通過參考:

sub complex_params { 
    my ($array1, $scalar, $hash, $array2) = @_; 

    # dereference 
    my @a1 = @$array1; 
    my @a2 = @$array2; 
    my %h = %$hash; 

    #... 
} 

# reference 
complex_params(\@some_array, $some_scalar, \%some_hash, \@other_array); 
+0

Thanksyou Matthias!它幫助:)將記住這個事情。 –

3

你在做什麼?

首先!不要試圖用原型:

sub ServiceStatus([email protected]){ 

} 

讓我們來看看,你想要什麼:

傳遞數組或哈希函數是一個很老的訣竅:

sub ServiceStatus{ 
my ($firstArgument, $refToSecondArgumentWhichIsArray) = @_; 

#return undef unless defined($firstArgument&&$refToSecondArgumentWhichIsArray); 
... 
} 

如何使用?

ServiceStatus($serverName, \@serverServices); 

如何處理參考?

$refToArray->[0]; <- first element of array you pass 
@{$refToArray} <- array you pass to function 
+0

感謝loldop爲您提供寶貴幫助。我在宣佈原型時弄錯了,但不幸的是在最後一部分沒有得到您的明確信息。 –

相關問題