2017-05-15 70 views
0

我班最好的方法看起来如下:的Perl:通过散列的数组子

package CSVKeepCols; 

use strict; 
use warnings; 
use Text::CSV; 
use Data::Dumper; 

my $text; 
my $del; 
my @cols; 
my $output = ''; 

sub load { 
    my $class = shift; 
    my $self = {}; 
    bless $self; 
    return $self; 
} 

sub input { 
    my $class = shift; 
    $text = shift; 
    return $class; 
} 

sub setOpts { 
    my ($class, $opts) = @_; 
    $del = $opts->{'delimeter'}; 
    @cols = $opts->{'columns'}; 
} 

sub process { 
    my @lines = split /\n|\r|\n\r|\r\n/, $text; 
    my $csv = Text::CSV->new({ sep_char => $del }); 

    foreach (@lines) { 
     die('Invalid CSV data') if !$csv->parse($_); 
     $output .= __filterFields($csv->fields()) . "\n"; 
    } 
} 

sub output { 
    return $output; 
} 

sub __filterFields { 
    my @fields = @_; 
    my $line = ''; 

    foreach (@cols) { 
     $line .= ',' if $line; 
     $line .= $fields[$_]; 
    } 

    return $line; 
} 

1; 

我使用这个类从我的代码是这样的:

$parser = load CSVKeepCols(); 
$parser->input($out); 
$parser->setOpts({'delimeter' => ',', 'columns' => [1,2]}); 
$parser->process(); 
$out = $parser->output(); 

我期待,setOpts子例程将采用散列{'delimeter' => ',', 'columns' => [1,2]},并从那里将它的值设置为$del,@cols(1,2),以便我可以循环访问@cols阵列。

然而,当我通过@cols__filterFields子程序尝试循环,收到错误

Use of reference "ARRAY(0x22e32e0)" as array index at CSVKeepCols.pm line 52.

我该如何解决这个问题?

+0

不是'[1,2]'的数组引用,而不是一个阵列;不应该将它存储在'my $ cols'中。然后解除引用(如'foreach(@ $ cols)')? – raina77ow

+0

如果所有的变量都是类变量,为什么要实例化一个对象呢? – bytepusher

+0

@ raina77ow你是对的,[1,2]是一个数组引用。我不知道。如果我存储解除引用的值,比如'@cols = @ {$ opts - > {'columns'}};',它就可以工作。但是,如何传递数组并使其工作?就像我尝试传递像'$ parser-> setOpts({'delimeter'=>',','columns'=>(1,2)});'并且结果只有数组的第一个值被存储在@ @ cols'数组中 –

回答

3

在setOpts,可以设置@cols = $opts->{columns};

$opts->{columns}包含对数组的引用([1,2])。

所以在__filterFields:

for (@cols){ 
    # $_ is an arrayref [1,2] 
    # you are using it as an index to retrieve a value from @fields 
    $line .= $fields[$_]; 
    # Thus the error: "use of reference ARRAY"..." as array index" 
    # You should be using an integer here. 
} 

为了修正它:

sub setOpts { 
    # ... 
    @cols = @{ $opts->{columns} }; 

} 

编辑:删除不必要的检查