2011-09-09 19 views
15

Tôi cần một số hướng dẫn với mã Perl sau. Khi tôi rời khỏi no strict 'refs', các sub hoạt động tốt. Nhưng nếu no strict 'refs' được lấy ra, sau đó tôi nhận được thông báo lỗi:Perl Không thể sử dụng chuỗi như là một biểu tượng ref trong khi refs nghiêm ngặt

Can't use string ("A") as a symbol ref while "strict refs" in use at test.pl 

Nó chết trong các đường đánh dấu là "Ở đây" dưới đây. sub cần mở (ghi>) tất cả các tệp từ A..Z và dựa trên regex từ tệp READ (LOG) đầu ra sẽ được ghi vào đầu ra tệp tương ứng.

use strict; 
use Text::CSV_XS; 
no strict 'refs'; 
... 
... 
sub file_split { 

    my ($i, $fh, @FH); 
    my ($file) = @_; 
    my (@alpha) = ("A".."Z"); 

    for (@alpha) {        
      $fh = $_ ; 
      open ($fh,">","$_-$file") || die $!;  <--------- HERE 
      push @FH, $fh; 
    } 

    my $csv = Text::CSV_XS->new({ binary => 1, 
            allow_whitespace => 1, 
            allow_loose_escapes => 1, 
            allow_loose_quotes =>1, 
            escape_char => undef , 
            sep_char => ',', 
            auto_diag=> 1 
            }); 
    open(LOG,"<", $file) || die $!; 
    while (my $row = $csv->getline(*LOG)) { 
      if ($row->[0] =~ /^(\w)/) { 
        print $1      <--------- HERE 
          "$row->[0]".",". 
          "$row->[1]" .",". 
          "$row->[2]" .",". 
          "$row->[3]" .",". 
          "$row->[4]".",". 
          "$row->[5]"."\n"; 

      } else { 
         print "Record skipped... --> $row->[0] <-- ... please verify  \n"; 
       } 
    } 
} 

Trả lời

8

Không chỉ định $fh = $_ nó không làm gì hữu ích.

@FH nên %FH và thay vì push thử:

$FH{ $_ } = $fh 

Thay $1 với $FH{ $1 }.

+0

Điều đó đã làm các trick. Và in $ 1 đã được thay thế để in {$ FH {$ 1}}. Cảm ơn. – Marcello

4

Bạn đang cố gắng sử dụng chuỗi ký tự dưới dạng tệp thủ công: trong vòng foreach của bạn, $_ nhận các giá trị "A", "B", v.v. Vì vậy, đừng làm thế. Chỉ cần tạo một filehandle mới và đẩy nó lên @FH.

6

Bạn đang yêu cầu perl để sử dụng giá trị của $ fh như tên của filehandle đây:

for (@alpha) {        
      $fh = $_ ; 
      open ($fh,">","$_-$file") || die $!;  <--------- HERE 
      push @FH, $fh; 
    } 

Bạn thay vào đó nên xem xét sử dụng một biến từ vựng và có mà autovivified thành một filehandle bởi mở, sau đó lưu trữ này trong một hash để có được nó sau này:

for (@alpha) {        
      open (my $fh,">","$_-$file") || die $!; 
      $handles{$_} = $fh; 
} 

để bạn có thể sử dụng nó sau đây:

while (my $row = $csv->getline(*LOG)) { 
      if ($row->[0] =~ /^(\w)/) { 
        print $handles{$1}      <--------- HERE 
          ... 
+0

Tính năng này hoạt động. Chỉ cần in $ handle {$ 1} để in {$ handles {$ 1}}. Cảm ơn. – Marcello

Các vấn đề liên quan