如何解决从排序块返回会发出“在排序中使用未初始化的值”警告,但仅在显式返回时
当我尝试从我的return
块中sort()
进入Perl时,我得到一种奇怪的行为:
#!/usr/bin/perl
use strict;
use warnings;
my @data = sort {
return &special_sort;
} qw/ 6 1 2 /;
use Data::Dumper;
print STDERR Data::Dumper->Dump([\@data]);
sub special_sort {
# (imagine some custom sorting logic here)
return $a <=> $b;
}
这将显示以下消息:
Use of uninitialized value in sort at ./mcve.pl line 6.
Use of uninitialized value in sort at ./mcve.pl line 6.
Use of uninitialized value in sort at ./mcve.pl line 6.
$VAR1 = [
6,1,2
];
如您所见,它也无法对列表进行排序。奇怪的是,以下sort子句可以在没有任何警告的情况下正常工作,并对数据进行正确的排序:
my @data = sort {
&special_sort;
} qw/ 6 1 2 /;
my @data = sort {
my $res = &special_sort;
return $res;
} qw/ 6 1 2 /;
my @data = sort {
return $a <=> $b;
} qw/ 6 1 2 /;
my @data = sort {
eval { return &special_sort; }
} qw/ 6 1 2 /;
问题0
这是怎么回事?为什么这四个有效,但第一个示例无效?它不应该是引起未定义行为的return
语句,因为有两个工作语句具有这种行为。
问题1
如果事实证明世界并不完美,而我不能(或不应该)return
,那么有效地做到这一点的优雅方法?我已经想出了[丑]:
my @data = sort {
my $rv;
SORT_WITH_RETURNS_KINDA: {
if (...) {
$rv = [something];
last SORT_WITH_RETURNS_KINDA;
}
if (...) {
$rv = [something else];
last SORT_WITH_RETURNS_KINDA;
}
}
return $rv;
} qw/ 6 1 2 /;
(注意:我做了一些检查,然后我逐渐弄清这是由于我对Perl如何处理Blocks和SUBs之间的困惑,因此产生了问题1。问题仍然是IMO有趣的问题,并且行为令人困惑为了清楚起见,我使用的是Perl 5.32.0。)
解决方法
这是bug。已应用修复程序,已解决了即将发布的Perl 5.34中的问题。
与此同时,您可以替换
return &special_sort;
使用
&special_sort; # Avoids the issue.
或
return scalar( &special_sort ); # Force scalar context.
或
return 0+&special_sort; # Force scalar context.
问题在于special_sort
在无效上下文中被错误地调用,上述变通办法可以避免或避免这种情况。
我最初声称您不能在return
块中使用sort
,因为它不是子变量。我还表示对没有错误报告的事实感到困惑。 @HåkonHægland指出return
的文档表明 可以在sort
块中使用。确实可以在其他情况下使用它。我报告了一个错误,现已修复。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。