Perl:打开还是[代码块]?
Posted
技术标签:
【中文标题】Perl:打开还是[代码块]?【英文标题】:Perl: open or [block of code]? 【发布时间】:2017-07-31 16:30:19 【问题描述】:我正在运行脚本 A,它将包含文件路径的 ARGV 提供给 perl 脚本 B。这是由
local @ARGV = ($file, $file2, etc.);
do scriptB.pl or die "scriptB has failed";
脚本 B 然后尝试打开文件:
open( my $fh_file, "<", $file )
or die "Could not open file '$file' $!";
但是,如果文件丢失,我不会在 B 中的“or die”之后得到引用的消息。相反,我会在 A 中得到 do scriptB.pl or die 消息。如果我从 A 中删除“or die”,脚本在 B 无声无息地死后继续执行,就好像没有出错一样。
我想知道是否有任何方法可以让 B 打印它的 die 消息?
更好的是,让 B 在无法打开文件后运行代码块的最佳方法是什么?例如,所述代码将写入一个单独的文件,列出丢失的文件,以便用户可以轻松追踪此类错误。
#something like
open( my $fh_file, "<", $file) or
print "the file could not be found";
die;
我发现在网上搜索帮助的唯一一件事是有人提到“或做”,但这给了我奇怪的语法错误,所以我不确定我是否正确使用它。
【问题讨论】:
“这给了我奇怪的语法错误” 请揭示这些奇怪的错误是什么,并显示产生它们的代码。 注意open ... or do ... ;
中的块后面需要一个分号
你需要在scriptB.pl
周围加上引号(如果你是use strict
,你应该这样做):do "scriptB.pl" or do if ( $@) ... else die $! ;
【参考方案1】:
如果您想继续使用open(...) or ...
语法,那么您可以使用do
。
open my $fh, '<', $file or do
...
;
但我认为切换到if
可能更清楚
if (! open my $fh, '<', $file)
...
甚至unless
unless (open my $fh '<', $file)
...
【讨论】:
因提供三个非常好的选项而受到支持。我不确定or do ...
语法是否不太清晰,因为它建立在人们(可能?希望?)已经习惯于看到的常见or die
模式之上。
当然。维护程序员的眼中是清晰 :-) 但至少语法错误的可能性大大增加,因为人们忘记了结束分号。
拒绝接受or do print(STDERR "...: $!\n"; die "ignored message"; ;
作为or die "...: $!\n"
的可接受替代方案。这种做法不应该采取!!!【参考方案2】:
我认为,如果您将脚本 B 放入模块中,并使用 use
或 require
加载它并使用明确的参数直接调用其中的函数,我认为您将获得更清晰的代码和更少的陷阱。
您在这里缺少的是do
在幕后涉及eval
,这会导致异常混淆。您可以通过将脚本 B 代码移动到模块中的函数中并调用它,或多或少地避免这种混淆。
(此外,perl 5.26 将与 do
有轻微的打嗝,其中当前目录将从目录查找中删除,出于安全考虑。use
和 require
有相同的打嗝,但这可能是不那么令人惊讶,因为您应该将模块放入您明确进入 @INC
加载路径的路径中。)
【讨论】:
【参考方案3】:die
不打印消息; die
抛出异常。当您捕获该异常时,您不会对传递给die
的消息执行任何操作。替换
local @ARGV = ($file, $file2, etc.);
do scriptB.pl or die "scriptB has failed";
与
local @ARGV = ($file, $file2, etc.);
do scriptB.pl or die "scriptB has failed: ". ( $@ || $! );
【讨论】:
以上是关于Perl:打开还是[代码块]?的主要内容,如果未能解决你的问题,请参考以下文章