我正在尝试创建一个脚本,该脚本将从模板生成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”,则脚本按预期工作。什么是词汇文件句柄导致它窒息?
答案 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
。