简体   繁体   English

Perl:打开还是[代码块]?

[英]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放到模块中,并userequire加载它,并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其中当前目录将从目录查找被删除,出于安全考虑, userequire具有相同的打嗝,但是这可能是那么令人惊讶,因为你应该把你的模块插入您明确进入@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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM