比较函数中未初始化的值在哪里?

Where is the uninitialized value in the compare function?

我试图自己找出错误,但没有发现。以下代码会产生警告(Perl 5.18.2 和 5.32.1 中存在相同问题)。

Use of uninitialized value in numeric comparison (<=>) at test.pl line 14.

同时执行 sort 的比较功能(因此,sort 操作未正确执行)。据我所知,散列值没有初始值,它们都有定义的数值。

use strict;
use warnings;

# Sort the occurrences of letters in a list of words, highest count first. 

my @words = ('ACGT','CCGT','CATG');  # Just an example
my $a = join '',@words;
my $l = length $a;
my %count = ();  

for (my $i = 0; $i < $l; $i++)  {
  my $x = substr( $a, $i, 1);
  $count{$x}++;
}

for my $x (sort { $count{$b} <=> $count{$a} } keys %count) {
  print "$x: $count{$x}\n";
} 

备注 :在使用 $count{$x}++; 语句递增它之前添加散列元素创建行没有帮助 - 结果相同(预期,如 undef 对增量操作计数为 0):

...
  $count{$x} = 0 unless defined $count{$x};
  $count{$x}++;
...

通常,sort 函数使用名为 $a$b 的两个包变量来进行排序。具体来说,sort 将当前包上名为 $a$b 的变量设置为当前排序值。这些不是您的 { $count{$b} <=> $count{$a} } 块的参数;它们是当前包中的全局变量。

现在,$b 可以了。因为你从来没有用它做任何其他事情,所以 Perl 会很好地选择包变量。但是您在代码的前面声明了一个名为 $a 的词法 (my) 变量,并且该词法正在隐藏包变量。

所以 sort 正在设置一个名为 $YourPackage::a 的变量,而您的代码正在访问一个名为 my $alocal 变量,与另一个无关。

您可以通过将 my $a = join '',@words; 变量更改为其他名称来解决此问题,实际上您应该这样做。由于历史原因,名称 $a$b$_ 在 Perl 中被不加区别地用于此类事情,因此最好不要让自己的变量命名为这些名称中的任何一个。

但是如果您不想(或不能)更改任何其余代码,您可以使用 our.

公开包变量
for my $x (sort { our $a; $count{$b} <=> $count{$a} } keys %count) {
  ...
}