[英]Perl: open or [block of code]?
I'm running script A which feeds ARGV containing the path to a file to perl script B. This is done by a 我正在运行脚本A,该脚本将ARGV包含到Perl脚本B的文件路径中。
local @ARGV = ($file, $file2, etc.);
do scriptB.pl or die "scriptB has failed";
Script B then tries to open the file: 然后,脚本B尝试打开文件:
open( my $fh_file, "<", $file )
or die "Could not open file '$file' $!";
However, if the file is missing I do not get the message quoted after "or die" in B. Instead I get the do scriptB.pl or die message in A. If I remove the "or die" from A, the script continues after B silently dies as if nothing went wrong. 但是,如果文件丢失,我不会在B中得到“或死”之后的消息。相反,我会在A中得到do scriptB.pl或die消息。如果我从A中删除“或死”,则脚本继续在B无声地死去之后,好像什么都没出错。
I was wondering if there was any way to get B to print its die message? 我想知道是否有任何办法让B打印其死消息?
Better yet, what is the best way to have B run a block of code after it fails to open the file? 更好的是,让B无法打开文件后运行代码块的最佳方法是什么? Said code would for example write to a separate file listing which files were missing so that the user may easily track down such errors.
所述代码例如将写入单独的文件,列出哪些文件丢失,以便用户可以容易地追踪此类错误。
#something like
open( my $fh_file, "<", $file) or {
print "the file could not be found";
die;
}
The only thing I've found searching the net for help was someone mentioning a "or do {}", but this is giving me strange syntax errors so I am not sure if I'm using it right. 我发现在网上寻求帮助的唯一一件事是有人提到“或做{}”,但这给了我奇怪的语法错误,因此我不确定我是否使用正确。
If you want to continue to use the open(...) or ...
syntax, then you could use do
. 如果要继续使用
open(...) or ...
语法,则可以使用do
。
open my $fh, '<', $file or do {
...
};
But I think it's probably clearer to switch to if
但我认为它可能是更清晰,切换到
if
if (! open my $fh, '<', $file) {
...
}
Or even unless
甚至
unless
unless (open my $fh '<', $file) {
...
}
I think you'll get clearer code with fewer gotchas if you put script B into a module, and load it with use
or require
and call the function(s) in there directly with clear parameters. 我认为,如果将脚本B放到模块中,并
use
或require
加载它,并use
清晰的参数直接在其中调用函数,则将获得更少的陷阱,从而使代码更清晰。
What you're missing here is that do
involves an eval
behind the scenes, and that results in the exception confusion. 您在这里所缺少的是,
do
涉及幕后eval
,并导致异常混乱。 You can more or less avoid that confusion by moving your script B code into a function in a module, and calling it. 您可以通过将脚本B代码移至模块中的函数中并对其进行调用来或多或少地避免这种混乱。
(Also, perl 5.26 will have a slight hiccup with do
wherein the current directory will be removed from the directory lookup, due to security concerns. use
and require
have the same hiccup, but this may be less surprising since you should put your module into a path you explicitly get into the @INC
load path.) (另外,Perl的5.26将有轻微的打嗝
do
其中当前目录将从目录查找被删除,出于安全考虑, use
和require
具有相同的打嗝,但是这可能是那么令人惊讶,因为你应该把你的模块插入您明确进入@INC
加载路径的路径。)
die
doesn't print a message; die
打印消息; die
throws an exception. die
引发异常。 When you catch that exception you don't do anything with the message passed to die
. 当您捕获到该异常时,您不会对传递给
die
的消息进行任何操作。 Replace 更换
local @ARGV = ($file, $file2, etc.);
do scriptB.pl or die "scriptB has failed";
with 同
local @ARGV = ($file, $file2, etc.);
do scriptB.pl or die "scriptB has failed: ". ( $@ || $! );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.