Perl中do语句异常表现:启用map转换后无输出问题咨询
问题
执行单行命令:
perl -MData::Dumper -e 'print Dumper do q(./dotest.pl)'
当dotest.pl中map转换代码处于注释状态时,得到预期输出:
$VAR1 = [ 1, 2, 3, 4 ];
dotest.pl的代码如下:
use strict; use warnings; my $x=1; if ($x) { my $ret = [ # map { my %h = (x => $_); \%h } 1..4 ]; } sub foo { 1 }
但取消map转换代码的注释后,上述单行命令不再输出任何内容。请问这是Perl 5.34.0的bug吗?
解答
这不是Perl 5.34.0的bug,核心原因和do操作符的行为、Perl编译/运行阶段的分工有关:
- Perl的顶层子程序定义(不在任何代码块内)是编译阶段处理的,不会作为运行时语句执行。因此
dotest.pl的运行时代码仅到if块结束,do FILE的返回值是if块最后一个表达式的求值结果。 - 注释map时,
if块内的赋值语句my $ret = [1..4]返回数组引用,do将该引用传递给Dumper,因此输出正常。 - 取消map注释后,理论上
do应该返回包含四个哈希引用的数组引用,Dumper会输出对应的结构。如果没有输出,大概率是以下场景:- 文件存在隐性语法问题(比如编码、换行符异常导致Perl解析失败),此时
do返回undef,可通过以下命令查看错误信息:perl -MData::Dumper -e ' my $res = do q(./dotest.pl); print Dumper($res); print "编译错误: $@" if $@; print "IO错误: $!" if !defined $res && !$@; ' - 终端输出被抑制、重定向或忽略,导致你看不到Dumper的输出结果。
- 文件存在隐性语法问题(比如编码、换行符异常导致Perl解析失败),此时
内容的提问来源于stack exchange,提问作者mpapec
相关产品推荐
相关产品推荐

