Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass array and hash data types to subroutines arguments in perl?

I am facing compilation error while declaring array type argument in perl subroutine defination. My complete code is below:

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.

Kindly help me debugging ths code. I am sure it would be a piece of cake for some.

like image 406
avimehenwal Avatar asked Dec 20 '12 09:12

avimehenwal


People also ask

How do you pass arguments to a subroutine in Perl?

Passing Arguments to a Subroutine You can pass various arguments to a subroutine like you do in any other programming language and they can be acessed inside the function using the special array @_. Thus the first argument to the function is in $_[0], the second is in $_[1], and so on.

How do I pass multiple arrays to a subroutine in Perl?

By using the backslash operator on a variable, subroutine, or value.


2 Answers

It is really simple: Do not use prototypes if you do not know how they work. To get your code running, change the subroutine declaration from:

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

to:

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

edit: If you need to pass more than one array/hash to a subroutine, or an array/hash should be passed-in before some other value(s), you have to pass it by reference:

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);
like image 142
Matthias Avatar answered Nov 15 '22 07:11

Matthias


Perl prototypes are not for naming parameters, or even for giving types to them, they are for creating evaluation contexts. You need to modify the subroutines like this:

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

or totally get rid of the prototype:

sub ServiceStatus {
  my ($serverName,@serverServices) = @_;   
  # ...
}
like image 34
perreal Avatar answered Nov 15 '22 08:11

perreal