Using single line conditional with require/rescue
Asked Answered
A

1

5

I want to avoid an error, if a require is not successfull.

I can do it with:

begin
  require 'unexisting_script' 
rescue LoadError
end

I tried to do the same with a one-line condition:

require 'unexisting_script' rescue LoadError

and get the error no such file to load -- unexisting_script (LoadError)

With other exceptions/commands I have no problem with a one line rescue, this works:

1 / 0 rescue ZeroDivisionError

I also tried to bracket the command, but withous success:

(require 'unexisting_script') rescue LoadError

I can put everything in one line with ;:

begin require 'unexisting_script'; rescue LoadError; end

but I'm still wondering, why the shortest version does not work.

I found some related questions, but none of them is mentioning a problem with require and rescue:

My question:

Can I use rescue in a one-line condition with require? If yes: how? If no: Why?

Antony answered 12/11, 2013 at 8:57 Comment(1)
possible duplicate of Does the Ruby rescue statement modifier really don't work with require? - But I keep the question open, I think the question has another purpose.Antony
H
10

You cannot specify the error class when you use rescue in postfix/oneliner notation. What rescue LoadError or rescue ZeroDivisionError means is that it will rescue a (subclass of) StandardError, and in such case, evaluate LoadError or ZeroDivisionError, which has no effect. Since ZeroDivisionError is a subclass of StandardError, it was captured, but LoadError is not, and it was not captured.

By the way, I cannot think of a use case where you want to not raise an error when a required file does not exist. Required files are dependencies, and if requiring them fails, then the program will not work correctly anyway. I feel a code smell in what you are doing. When failure of loading a file does not mess the program, that is usually when you should be using load instead of require.

Horrorstruck answered 12/11, 2013 at 9:5 Comment(4)
For the usage: My program uses a library to export to a special format. If it is not available, I give the message "Export format XY not supported" - but only, if somebody requests it. In my special case, I don't expect this specific export format is needed by anybody if the corresponding library is not available. As an alternative I could check in advance if the library is installed, but I think that's more work as just ignore the load error.Antony
@sawa: Sometimes this is needed to support different alternative libraries with similar APIs. e.g. (when using Ruby 1.8) fastercsv and csv. If one is not available, just use the other one. Another use-case is for JSON libraries, e.g in multi_json.Calamanco
knut and Holger, I see. That makes sense.Horrorstruck
Ah, I just recently found this discussion. I remember discussing this with sawa on the official bug tracker too. :) My use case is similar to knut, but more that I need to remain flexible and specify "weaker" dependencies - stuff that users MAY have, but which may not be vital. Since I use tons of such requires, I also have a need to make this short-ish. The begin/rescue clause is just too long; since I space my code out, I like need 5 lines of code for it. rescue nil on the same line or whatever, is not elegant either; btw, require() is used a LOT more than load() in general.Emilyemina

© 2022 - 2024 — McMap. All rights reserved.