2012-12-20 28 views
5

Tôi đang đối mặt với lỗi biên dịch trong khi khai báo đối số kiểu mảng trong việc loại bỏ chương trình con perl. mã hoàn chỉnh của tôi là dưới đây:Làm cách nào để truyền các kiểu dữ liệu mảng và băm cho các đối số con trong 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"; 
    } 
    } 
} 

LẬP LỖI

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

Vui lòng giúp tôi gỡ rối ths mã. Tôi chắc chắn nó sẽ là một miếng bánh cho một số người.

+3

perl không có cơ chế khai báo các loại đối số. nguyên mẫu trông giống như họ làm điều đó ngay từ cái nhìn đầu tiên, nhưng trong thực tế phục vụ một mục đích hoàn toàn khác nhau; bạn không nên sử dụng chúng. – ysth

Trả lời

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

} 
+0

Cảm ơn RobEarl vì câu trả lời quý giá của bạn –

+0

Nhận xét này rất hữu ích đối với tôi (vào năm 2015) khi đã làm việc trong PHP và JavaScript trong hơn một năm và quên ngữ cảnh @_ với người đăng ký trong Perl. Cảm ơn –

6

Nguyên mẫu Perl không dành cho tham số đặt tên, hoặc thậm chí cho việc đưa các loại cho chúng, để tạo ngữ cảnh đánh giá. Bạn cần phải sửa đổi các thủ tục con như thế này:

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

hoặc hoàn toàn thoát khỏi nguyên mẫu:

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

Thật đáng kinh ngạc. Có tin nhắn của bạn to và rõ ràng :) Cảm ơn –

9

Nó thực sự đơn giản: Không sử dụng prototypes nếu bạn không biết làm thế nào họ làm việc. Để nhận được mã chạy của bạn, thay đổi khai báo chương trình con từ:

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

tới:

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

chỉnh sửa: Nếu bạn cần phải vượt qua nhiều hơn một mảng/băm để một chương trình con, hoặc một mảng/băm nên được thông qua trước một số giá trị khác, bạn phải chuyển nó theo tham chiếu:

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! Nó đã giúp :) Hãy ghi nhớ điều này. –

3

bạn đang làm gì?

Đầu tiên! Đừng cố gắng sử dụng nguyên mẫu:

sub ServiceStatus([email protected]){ 

} 

Hãy xem, những gì bạn muốn:

Đi qua mảng hoặc băm để hàm được một thủ thuật rất cũ:

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

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

Làm thế nào để sử dụng này?

ServiceStatus($serverName, \@serverServices); 

Và phải làm gì với refs?

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

Cảm ơn loldop vì sự giúp đỡ quý giá của bạn. Tôi đã nhận sai lầm của tôi trong khi tuyên bố nguyên mẫu nhưng tiếc là đã không nhận được thông điệp rõ ràng của bạn trong phần cuối cùng. –