如何将here-doc中嵌入的代码打印到词法文件句柄

时间:2017-04-18 19:52:34

标签: perl file-io heredoc

我正在尝试创建一个脚本,该脚本将从模板生成perl代码,而我无法理解抛出的错误以及为什么我的解决方法会修复它。

这个例子是人为的,但它证明了这个问题:

use strict;
use warnings;

my $name = shift; # from @ARGV
my $file = sprintf "%s.pm", $name;

open my $fh, ">", $file
  or die "error: open(>, '$file'): $!";

print $fh << "MODULE";
package $name;

#
# blah blah
#

use strict;
use warnings;

require Exporter;

our \@ISA       = qw| Exporter |;
our \@EXPORT    = qw| |; # automatic exports
our \@EXPORT_OK = qw| |; # on-demand exports

# CODE

1;
MODULE

close $fh;

运行此脚本时,出现以下错误:

$ perl script.pl Foo
Invalid version format (non-numeric data) at script.pl line 11, near "package "
syntax error at script.pl line 11, near "package $name"
BEGIN not safe after errors--compilation aborted at script.pl line 17.

最初这个脚本只是打印到stdout而不是写入文件 - 没有抛出任何错误。在添加文件处理并收到此错误之后,我尝试使用一个裸文件句柄 - 再次没有抛出错误。

因此,如果我只是将“$ fh”替换为“FH”,则脚本按预期工作。什么是词汇文件句柄导致它窒息?

2 个答案:

答案 0 :(得分:2)

var arr = ["A" , "B", "C" , "D" , "E"]; var errDone = false; var cntr = 0; arr.forEach(function (arrayItem) { var options = { method: 'GET', url:"some_url", headers: {...} }; request(options, function (error, response, body) { if (error) { if (!errDone) { // latch error so we don't call next(error) multiple times errDone = true; next(error); } } else { // process result here // check if this is the last response ++cntr; if (cntr === arr.length) { // all responses done here next(); } } }); 标记此处文档后应该没有空格,所以

<<

应该是

print $fh << "MODULE";

或更整洁

print $fh <<"MODULE";

或者

print $fh <<MODULE;

由于print $fh (<< "MODULE"); 被视为左移运算符,Perl继续尝试编译<<语句。找不到有效的包名称,它会尝试使用package作为版本号,并抱怨因为它不是一个

答案 1 :(得分:1)

Perl是一种含糊不清的语言。这意味着它并不总是很清楚它应该如何解析。在某些情况下,perl必须猜测如何解析某些内容。

中存在语法歧义
print $fh << "MODULE";

具体来说,<<可以是左移运算符或here-doc的开头。

您可以通过两种方式解决问题。

  • 您可以消除歧义:

    print $fh +<< "MODULE";
    

    print $fh (<< "MODULE");
    

    print { $fh } << "MODULE";
    

    $fh->print(<< "MODULE");
    
  • 您可以欺骗perl进行正确猜测:

    print $fh <<"MODULE";
    

请注意print $fh +<< "MODULE";引入了另一种歧义。 +是二元或一元+运算符吗?值得庆幸的是,它根据需要被解释为一元 - +

顺便说一下,<<"MODULE"可以缩短为<<MODULE