Как передать типы данных массива и хэша в аргументы подпрограмм в 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$servn";
     }
     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.

любезно помогите мне отлаживать код ths. Я уверен, что для некоторых это было бы проще простого.

4 ответов


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

}

Это действительно просто: не используйте прототипы если вы не знаете, как они работают. Чтобы запустить код, измените объявление подпрограммы на:

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

в:

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

edit: Если вам нужно передать несколько массивов/хэшей подпрограмме, или массив/хэш должен быть передан перед каким-либо другим значением(значениями), вы должны передать его по ссылке:

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);

прототипы Perl не предназначены для именования параметров или даже для предоставления им типов, они предназначены для создания контекстов оценки. Вам нужно изменить подпрограммы следующим образом:

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

или полностью избавиться от прототипа:

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

что ты делаешь?

первая! Не пытайтесь использовать прототипы:

sub ServiceStatus($@){

}

давайте посмотрим, что вы хотите:

передача массива или хэша в функцию-очень старый трюк:

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