I'm not sure what you're trying to accomplish other than trying to write Perl with Ruby. You have to consider the fact that Perl's open
returns "nonzero on success, the undefined value otherwise. If the open involved a pipe, the return value happens to be the pid of the subprocess."
Ruby's File::open
however raises an exception Errno::ENOENT
which is completely different behavior than returning some Ruby equivalent to undefined
(I guess nil
).
Write Ruby if your tool is Ruby. Write Perl if your tool is Perl. Don't write Perl if your tool is Ruby. Don't write Ruby if your tool is Perl.
UPDATE:
As @steenslag answered, simply not rescue
ing the exception is sort of an equivalent since the exception will act as an implicit die
equivalent of Perl.
File.open filename
However you are now restricted to outputting the exception's message
value as the output. For example:
in `initialize': No such file or directory @ rb_sysopen - filename (Errno::ENOENT)
If you need to output your own message you'll have to catch the exception and handle it. This is the behavior of File.open
so you'll have to use it as intended. I would also argue you should explicitly specify the exception type to catch, as well as write to $stderr
:
begin
File.open filename do |f|
puts f.gets
# ...
end
rescue Errno::ENOENT => e
$stderr.puts "Caught the exception: #{e}"
exit -1
end
Which would output the message specified to standard error and exit the program with an non-zero status (which is the behavior of die
):
Caught the exception: No such file or directory @ rb_sysopen - filename
For the record I absolutely love Perl. Ruby actually shares a lot of similar characteristics of Perl (among other languages and paradigms). But when I'm writing Perl I use Perl idioms, and when I write Ruby I use Ruby idioms. The reason I'm stressing "don't write Perl with Ruby" so much is because languages have their idioms for a reason and you can end up making your colleagues mad if you don't do things "the Ruby way" or "the Perl way" with each respective language.
open || die
does not "silently ignore any errors". In fact, the Ruby code above is merely printing an error message and continuing on, where the Perl example stops execution of the program. – Kimmelexit
raises theSystemExit
exception and does NOT continue on unless it is explicitly caught. ruby-doc.org/core-2.1.1/Kernel.html#method-i-exit. The only thing I see the example doing "wrong" is not setting the appropriate exit status. – Coprophiliaexit
was not in the question. Theexit
was added five minutes after I posted my comment above. Here's the original question that I responded to. stackoverflow.com/revisions/22898310/1 – Kimmelrescue
an exception "catch"? Would would happen if the rescue block wasn't there? It looks to me like the OP is trying to replicate the default behaviour! – Loyceloydrescue
is analogous tocatch
in languages like C++ and Java. If the rescue block wasn't there then the program will print out the exception and just end since the exception wasn't caught (again, similar to C++ and Java). What do you mean by "default behavior?" – CoprophiliaFile.open(filename, 'r')
, which would terminate the program with a message just like the Perl code he shows. – Weatherfordrescue
block. – CoprophiliaFile::exists?
orFile::readable?
for example) and before the attempt to open withFile::open
orFile::new
. It's also not flow control; We're trying to open a file. The failure to open a file is an unexpected condition which is why it raises the Exception in the first place. – Coprophilia