Perl中`print $fh <<'EOF'`形式here-doc执行异常问题排查
问题根源:Perl Here-Doc的结束标记缩进规则
你的问题其实是踩了Perl Here-Doc语法的一个常见坑——结束标记的缩进要求非常严格!
具体来说:
- 当你使用
<< 'TAG'这种单引号包裹的Here-Doc标记时,Perl要求结束标记TAG必须完全顶格书写,不能有任何前导空格或制表符。 - 你的代码里,
TAG前面加了缩进(和print语句对齐),导致Perl根本没把它识别成Here-Doc的结束标记。这就引发了两个问题:- Perl会把后面的
close($fh);也当成Here-Doc的内容,继续往下解析; - 因为Here-Doc没有正确终止,Perl会误把
BEGIN { something; }当成当前代码的一部分去执行——而你开启了strict subs,不允许裸词something,所以直接抛出了运行时错误。
- Perl会把后面的
两种修正方案
方案1:让结束标记顶格写
最直接的解决办法就是把TAG完全顶格,去掉前导空格:
use strict; use warnings; if (open(my $fh, '>', '/tmp/test')) { print $fh << 'TAG'; BEGIN { something; } TAG close($fh); }
这样Perl就能正确识别Here-Doc的边界,把BEGIN { something; }原样写入文件,不会执行其中的代码。
方案2:用<<-TAG支持制表符缩进
如果想保持代码的缩进美观,可以使用带连字符的<<-TAG语法,此时允许用制表符(注意只能是制表符,空格不行)缩进结束标记:
use strict; use warnings; if (open(my $fh, '>', '/tmp/test')) { print $fh <<-TAG; BEGIN { something; } TAG # 这里的缩进必须是制表符,不能用空格 close($fh); }
⚠️ 注意:这个语法只支持制表符缩进,用空格的话Perl还是会识别不到结束标记,一定要注意区分。
修正之后,你的代码就能正常工作,把指定内容写入文件,不会再触发strict subs的错误了。
内容的提问来源于stack exchange,提问作者U. Windl
相关产品推荐
相关产品推荐

