为什么将此语句视为字符串而不是结果?

rev*_*nge 5 regex string perl

我正在尝试对大量字符串(蛋白质序列)执行一些基于组合的过滤.
我写了一组三个子程序来处理它,但我在两个方面遇到麻烦 - 一个是小的,一个是主要的.小麻烦是当我使用List :: MoreUtils'成对'时,我得到关于使用的警告,$a并且$b只有一次,并且它们未被初始化.但我相信我正在调用这种方法(基于CPAN的输入和网上的一些例子).
主要的麻烦是错误"Can't use string ("17/32") as HASH ref while "strict refs" in use..."

看起来这只有在foreach循环输入&comp将散列值作为字符串而不是评估除法运算时才会发生.我确定我犯了一个菜鸟错误,但无法在网上找到答案.我第一次看到perl代码是在上周三...

use List::Util;
use List::MoreUtils;
my @alphabet = (
 'A', 'R', 'N', 'D', 'C', 'Q', 'E', 'G', 'H', 'I',
 'L', 'K', 'M', 'F', 'P', 'S', 'T', 'W', 'Y', 'V'
);
my $gapchr = '-';
# Takes a sequence and returns letter => occurrence count pairs as hash.
sub getcounts {
 my %counts = ();
 foreach my $chr (@alphabet) {
  $counts{$chr} = ( $_[0] =~ tr/$chr/$chr/ );
 }
 $counts{'gap'} = ( $_[0] =~ tr/$gapchr/$gapchr/ );
 return %counts;
}

# Takes a sequence and returns letter => fractional composition pairs as a hash.
sub comp {
 my %comp = getcounts( $_[0] );
 foreach my $chr (@alphabet) {
  $comp{$chr} = $comp{$chr} / ( length( $_[0] ) - $comp{'gap'} );
 }
 return %comp;
}

# Takes two sequences and returns a measure of the composition difference between them, as a scalar.
# Originally all on one line but it was unreadable.

sub dcomp {
 my @dcomp = pairwise { $a - $b } @{ values( %{ comp( $_[0] ) } ) }, @{ values( %{ comp( $_[1] ) } ) };
 @dcomp = apply { $_ ** 2 } @dcomp;
 my $dcomp = sqrt( sum( 0, @dcomp ) ) / 20;
 return $dcomp;
}
Run Code Online (Sandbox Code Playgroud)

对任何答案或建议表示赞赏!

out*_*tis 2

%{ $foo }将视为$foo哈希引用并取消引用它;类似地,@{}将取消引用数组引用。由于comp返回哈希作为列表(当传入和传出函数时,哈希变成列表)而不是哈希引用,因此这%{}是错误的。您可能会忽略%{}, butvalues是一种特殊形式,需要哈希,而不是作为列表传递的哈希。comp要传递to的结果valuescomp需要返回一个哈希引用,然后取消引用。

您的还有另一个问题,即(如文档所述)“以明显随机的顺序返回”的dcomp顺序,因此传递给块的值不一定是相同的字符。您可以使用哈希切片来代替。我们现在回到返回哈希值(作为列表)。valuespairwisevaluescomp

sub dcomp {
    my %ahisto = comp($_[0]);
    my %bhisto = comp($_[1]);
    my @keys = uniq keys %ahisto, keys %bhisto;
    my @dcomp = pairwise { $a - $b } , @ahisto{@keys}, @bhisto{@keys};
    @dcomp = apply { $_ ** 2 } @dcomp;
    my $dcomp = sqrt( sum( 0, @dcomp ) ) / 20;
    return $dcomp;
}
Run Code Online (Sandbox Code Playgroud)

这并没有解决如果一个字符仅出现在 和 之一中会发生什么$_[0]情况$_[1]

uniq留给读者作为练习。