使用@l和Perl读取数组和多个标量

时间:2014-06-26 19:42:25

标签: perl variables subroutine

我试图将一些参数传递给子例程

sub mean 
{
my (@values, $chan1, $chan2, $chan3, $chan4) = @_;
print   $chan1, $chan2, $chan3, $chan4;
my $ave_value = sum($values[$chan1],$values[$chan2],$values[$chan3],$values[$chan4])/@values;
}

致电

 push (@avg_value , mean(@datachunk,$subchannel[0],$subchannel[1],$subchannel[2],$subchannel[3]));

我在数组元素中获得未初始化的错误值。我假设它是因为我尝试读取值的方式。这是正确的方法吗?

2 个答案:

答案 0 :(得分:3)

您的阵列分配正在耗尽所有参数。

例如,在下文中,$foo$bar将始终未定义,@array将包含4个元素:

my (@array, $foo, $bar) = (1,2,3,4);

以下是两种可能的解决方案:

1)先放置标量,然后放入数组:

sub mean  {
    my ($chan1, $chan2, $chan3, $chan4, @values) = @_;
    print   $chan1, $chan2, $chan3, $chan4;
    my $ave_value = sum(@values[$chan1, $chan2, $chan3, $chan4])/@values;
}

# Calling method:
mean($subchannel[0], $subchannel[1], $subchannel[2], $subchannel[3], @datachunk)

2)或者,您可以通过引用传递数组:

sub mean  {
    my ($arrayref, $chan1, $chan2, $chan3, $chan4) = @_;
    print   $chan1, $chan2, $chan3, $chan4;
    my $ave_value = sum(@{$arrayref}[$chan1, $chan2, $chan3, $chan4]) / @$arrayref;
}

# Calling method:
mean(\@datachunk, $subchannel[0], $subchannel[1], $subchannel[2], $subchannel[3])

然而,最严格的解决方案是重新设计您的代码。你想要的只是一个列表的平均值。因此,只需直接传递列表而不是具有索引值的数组。

sub mean  {
    return @_ ? sum(@_) / @_ : die "Mean of 0 numbers is undefined";
}

# Calling method:
mean(@datachunk[@subchannel[0..3]])

答案 1 :(得分:3)

问题在于Perl并不像Ruby那样聪明,因此当您使用赋值将参数收集到mean

my (@values, $chan1, $chan2, $chan3, $chan4) = @_;

您将@_整个分配给@values,将$chan1$chan2等设置为undef

通常,特别是如果要将数组参数与标量组合在一起,则应通过 reference 传递数组。所以你的子程序可能是

sub mean {
  my ($values, $chan1, $chan2, $chan3, $chan4) = @_;
  print "$chan1, $chan2, $chan3, $chan4\n";
  my $avg = sum(
    $values->[$chan1],
    $values->[$chan2],
    $values->[$chan3],
    $values->[$chan4]
  ) / @values;
}

你会把它称为

push(@avg_value, mean(
  \@datachunk,
  $subchannel[0], $subchannel[1], $subchannel[2], $subchannel[3]
));

但是,如果仅传递值列表,则mean子例程将更加普遍有用。例如,如果您将mean定义为

sub mean { sum(@_) / @_ }

然后您可以使用数组切片调用它,就像这样

push(@avg_value, mean(@datachunk[@subchannel[0..3]]));

或者,如果这对你来说太多了,那么拆分切片

my @chunk_indices = @subchannel[0..3];
my @values = @datachunk[@chunk_indices];
push @avg_value, mean(@values));

我希望这会有所帮助