我的Perl程序包含两个与此类似的块:
open my $file, '>', $filename or do{
print "Failed to open file\nFile not saved\n";
return;
}
当我运行它时,我得到了这个:
"my" variable @lines masks earlier declaration in same scope at myfile.pl line 43.
"my" variable @args masks earlier declaration in same scope at myfile.pl line 43.
"my" variable @args masks earlier declaration in same statement at myfile.pl line 43.
"my" variable @args masks earlier declaration in same scope at myfile.pl line 47.
syntax error at myfile.pl line 19, near "$i ("
Global symbol "$i" requires explicit package name at myfile.pl line 20.
Global symbol "$file" requires explicit package name at myfile.pl line 21.
Global symbol "$i" requires explicit package name at myfile.pl line 21.
Global symbol "$file" requires explicit package name at myfile.pl line 23.
syntax error at myfile.pl line 24, near "}"
syntax error at myfile.pl line 35, near "}"
syntax error at myfile.pl line 44, near "}"
syntax error at myfile.pl line 54, near "}"
Can't use global @_ in "my" at myfile.pl line 57, near ", $_"
myfile.pl has too many errors.
但是当我用它替换它时:
do{
print "Failed to open file\nFile not saved\n";
return;
}unless open my $file, '>', $filename;
所有错误立即消失,程序运行正常。我有use strict
和use warnings
。
有谁知道为什么会这样?我的括号有什么问题吗?更改open
函数中的间距不起作用。
编辑:我已将print
语句替换为warn
。
答案 0 :(得分:3)
在第一种情况下
open ( my $file, '>', $filename ) or do {
print "Failed to open file\nFile not saved\n";
return;
}
my $file
在do
块之外的范围内,而在
do {
print "Failed to open file\nFile not saved\n";
return;
} unless open my $file, '>', $filename;
它是块的本地。请注意,这也意味着您在打开它之后无法使用$file
来写入,因为它会立即再次关闭。
你可以
为每个文件句柄使用不同的标识符
在第一次
my
来电中的open
将每个open
及后续文件操作包含在其自己的块中,如下所示
{
open( my $file, '>', $filename ) or do{
print "Failed to open file\nFile not saved\n";
return;
};
# Write to $file
}
答案 1 :(得分:0)
我认为这与子程序有关。否则,为什么你有return
?
使用标准if
声明。这样,程序正在做的更清楚:
my $file;
if ( not open $file, ">", $filename ) {
warn qq(Failed to open file "$filename"\nFile not saved\n);
return;
}
注意:
$file
之外定义if
。否则,$file
在if
之外变为未定义。可能不是你想要的。 (并且是造成问题的原因)。warn
。这会打印到STDERR
而不是STDOUT
。它还会警告开发人员浏览代码,这是某种错误消息,可能需要注意。最新的样式编程风格是让子程序死于错误。这意味着您可以在子例程中执行此操作:
open my $fh, ">", $filename
or die qq(Can't open "$filename"\n);
现在,如果开发人员不希望程序死亡,开发人员现在必须使用eval
来主动处理错误:
my $fh;
eval {
$fh = openlog ( $filename );
};
if ( $@ ) {
warn qq(Can't open log file "$filename". No log will be written);
}
这是异常处理编程语言(如Python和Java)强制开发人员面对错误的方式。否则,开发人员可以简单地假设子例程有效。在Perl中,你会一直看到这样的东西:
send_email( email_address( $user ), $message );
嗯......在程序尝试发送电子邮件之前,email_address()
是否确实返回了电子邮件地址?