2012-12-20 8 views
5

Mam do czynienia z błędem kompilacji podczas deklarowania argumentu typu tablicy w definicji podprogramu perl. mój pełny kod jest poniżej:Jak przekazywać typy danych tablicowych i mieszających do argumentów podprogramów w perlu?

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"; 
    } 
    } 
} 

COMPILATION ERROR

>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. 

uprzejmie mi pomóc debugowania ths kod. Jestem pewien, że dla niektórych byłby to kawałek ciasta.

+3

perl nie ma mechanizmu do zadeklarowania typów argumentów. prototypy wyglądają tak, jak robią to na pierwszy rzut oka, ale w rzeczywistości służą zupełnie innemu celowi; nie powinieneś ich używać. – ysth

Odpowiedz

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

} 
+0

Dzięki RobEarl za twoją cenną odpowiedź –

+0

Ten komentarz był mi pomocny (w 2015 roku), gdy pracowałem w PHP i JavaScript przez ponad rok, i zapomniałem o kontekście @_ z subami w Perlu. Dzięki –

6

Perl prototypy nie są dla parametrów nazewnictwa, a nawet za udzielenie typy do nich, są one do tworzenia kontekstu oceny. Trzeba zmodyfikować podprogramów tak:

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

lub całkowicie pozbyć prototypu:

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

Doskonałe perreal. Mam wiadomość głośno i wyraźnie :) Dzięki –

9

To jest bardzo proste: Nie używaj prototypes jeśli nie wiem, jak one działają. Aby uzyskać uruchomiony kod, zmienić deklarację podprogramu z:

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

do:

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

EDIT: Jeśli trzeba przejść więcej niż jedną tablicę/hash do podprogramu lub tablicę/hash należy przekazać przed jakąś inną wartością, musisz przekazać to przez odniesienie:

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! Pomogło :) Będzie to miało na uwadze. –

3

co robisz?

Po pierwsze! Nie staraj się używać prototypów:

sub ServiceStatus([email protected]){ 

} 

Zobaczmy, co chcesz:

Mijając tablicę lub hash do funkcji jest bardzo stara sztuczka:

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

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

Jak tego używać?

ServiceStatus($serverName, \@serverServices); 

Co należy zrobić z dokumentami?

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

Dziękuję firmie Loldop za cenną pomoc. Dostałem swój błąd podczas deklarowania prototypów, ale niestety nie dostałem twojego jasnego komunikatu w ostatniej części. –

Powiązane problemy