打开文件并在无法在 Ruby 中打开文件时执行"rescue"的最清晰方法是什么



我现在使用以下代码处理此问题

begin
  File.open(filename, 'r')
rescue
  print "failed to open #{filename}n"
  exit
end

有没有办法像Perl一样更容易地做到这一点'open (IN, $filename) || die "failed to open $filenamen"'谢谢。

File.open("doesnotexist.txt", 'r')

就够了。如果该文件不存在,这将引发异常。这不会被捕获,因此程序退出。

# =>test6.rb:1:in `initialize': No such file or directory @ rb_sysopen - doesnotexist.txt (Errno::ENOENT)

除了尝试用 Ruby 编写 Perl 之外,我不确定你想完成什么。你必须考虑这样一个事实,即 Perl 的open在成功时返回"非零值,否则返回未定义的值。如果打开涉及管道,则返回值恰好是子流程的 pid。

然而,Ruby 的File::open引发了一个异常Errno::ENOENT这与返回一些等效于 undefined 的 Ruby 的行为完全不同(我猜nil)。

如果你的工具是 Ruby,请编写 Ruby。如果你的工具是Perl,那就写Perl。如果你的工具是Ruby,就不要写Perl。如果你的工具是Perl,就不要写Ruby。

更新:

正如@steenslag所回答的,简单地不rescue异常是一种等价物,因为异常将充当 Perl 的隐式die等价物。

File.open filename

但是,您现在只能将异常的message值输出为输出。例如:

in `initialize': No such file or directory @ rb_sysopen - filename (Errno::ENOENT)

如果您需要输出自己的消息,则必须捕获异常并处理它。这是File.open的行为,因此您必须按预期使用它。我还认为您应该明确指定要捕获的异常类型,并写入$stderr

begin
  File.open filename do |f|
    puts f.gets
    # ...
  end
rescue Errno::ENOENT => e
  $stderr.puts "Caught the exception: #{e}"
  exit -1
end

这将输出指定为标准错误的消息并以非零状态退出程序(这是die的行为):

Caught the exception: No such file or directory @ rb_sysopen - filename

为了记录,我非常喜欢Perl。Ruby实际上与Perl有很多相似的特征(以及其他语言和范式)。但是当我写Perl时,我使用Perl习语,当我写Ruby时,我使用Ruby习语。我之所以如此强调"不要用 Ruby 编写 Perl",是因为语言有其习语是有原因的,如果你不对每种语言做"Ruby 方式"或"Perl 方式"的事情,你最终可能会让你的同事生气。

最新更新