"rescue" modifier and LoadError

Hi,

why doesn't "CCCC" get printed?

  [loaderr.rb]

···

----
  1/0 rescue ZeroDivisionError
  puts "AAAA"
  begin ; require "nonexisting" ; rescue LoadError ; end
  puts "BBBB"
  require "nonexisting" rescue LoadError
  puts "CCCC"
  ----

Thanks in advance,

Bertram

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

···

On Mon, Jun 1, 2020 at 8:12 AM Bertram Scharpf <lists@bertram-scharpf.de> wrote:

Hi,

why doesn't "CCCC" get printed?

  [loaderr.rb]
  ----
  1/0 rescue ZeroDivisionError
  puts "AAAA"
  begin ; require "nonexisting" ; rescue LoadError ; end
  puts "BBBB"
  require "nonexisting" rescue LoadError
  puts "CCCC"
  ----

Thanks in advance,

Bertram

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Hi,

>
> why doesn't "CCCC" get printed?
>
> [loaderr.rb]
> ----
> 1/0 rescue ZeroDivisionError
> puts "AAAA"
> begin ; require "nonexisting" ; rescue LoadError ; end
> puts "BBBB"
> require "nonexisting" rescue LoadError
> puts "CCCC"
> ----
>
stackoverflow.com/questions/19924795/using-single-line-conditional-with-require-rescue

Thank you!

I understand: The `rescue` modifier requires the exception
to be a `StandardError` and doesn't complain when given an
exception class that was not derived from `StandardError`.

Please allow me some remarks and questions.

1. Is there really no official reference where I can look
this up? Where can I find this fact in the source code?

2. The above answer says there is no use case to rescue a
LoadError. I have one: I `require` a lot of Ruby files from
inside my editor where I do a lot of calculations with Ruby.
When I copy the configuration files from one machine to
another, I do not have to do all the Gem installs at once
when requiring with a rescue of LoadError.

3. Why doesn't Ruby complain or at least warn when I give a
non-`StandardError` exception after the `rescue` modifier?

Bertram

···

On Monday, 01. Jun 2020, 08:28:58 -0300, Clavius Tales wrote:

On Mon, Jun 1, 2020 at 8:12 AM Bertram Scharpf <lists@bertram-scharpf.de> wrote:

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

Hi,

> > why doesn't "CCCC" get printed?
> >
> > [loaderr.rb]
> > ----
> > 1/0 rescue ZeroDivisionError
> > puts "AAAA"
> > begin ; require "nonexisting" ; rescue LoadError ; end
> > puts "BBBB"
> > require "nonexisting" rescue LoadError
> > puts "CCCC"
1. Is there really no official reference where I can look
this up? Where can I find this fact in the source code?

...

3. Why doesn't Ruby complain or at least warn when I give a
non-`StandardError` exception after the `rescue` modifier?

Bertram

Hello Bertram,
I think you have misunderstood the meaning of the value after the rescue
modifier.

As others already told you, the rescue modifier always rescues exceptions
derived from StandardError. To be more explicit, this doesn't only mean you
can't rescue exceptions not derived from StandardError, it also means you
can't choose which exceptions are rescued: for example, you can't use the
rescue modifier to rescue a ZeroDivisionError but not an ArgumentError. For
example,

1/0 rescue ArgumentError

won't raise any exception.

To find out the meaning of the statement after the rescue modifier, you can run
the line above in irb:

irb(main):001:0> 1/0 rescue ArgumentError
=> ArgumentError

This shows you that the value returned by the the whole expression is the
result of the statement after the rescue modifier. Another example:

irb(main):003:0> 1/0 rescue 27
=> 27

irb(main):007:0> "hello"[:a] rescue "x"
=> "x"

In short, the meaning of the rescue modifier is the following:
- attempt to execute the statement before "rescue"
- if an exception derived from StandardError is raised, execute the statement
after "rescue"

After all of this, you can see that the answer to your question, why doesn't
ruby complain when i write 1/0 rescue LoadError?, is that it doesn't complain
because what you wrote is perfectly correct. It means:
- execute 1/0
- if it raises an exception, use the class LoadErorr as the result of the
whole expression.

For example:

irb(main):008:0> x = 1/0 rescue LoadError
=> LoadError
irb(main):009:0> x.class
=> Class
irb(main):010:0> x
=> LoadError
irb(main):011:0>

As for your first question, I looked this up in the book "The ruby programming
language" by Flanagan and Matsumoto, but it's quite old (it's been published
in 2008 and only covers ruby 1.8 and ruby 1.9). I don't know whether there are
more recent references.

I hope this helps

Stefano

···

On martedì 2 giugno 2020 07:55:36 CEST Bertram Scharpf wrote:

On Monday, 01. Jun 2020, 08:28:58 -0300, Clavius Tales wrote:
> On Mon, Jun 1, 2020 at 8:12 AM Bertram Scharpf <lists@bertram-scharpf.de> wrote:

Arrrgh! You're right. Sorry for the noise.

Bertram

···

On Tuesday, 02. Jun 2020, 10:01:12 +0200, Stefano Crocco wrote:

I think you have misunderstood the meaning of the value after the rescue
modifier.

As others already told you, the rescue modifier always rescues exceptions
derived from StandardError. To be more explicit, this doesn't only mean you
can't rescue exceptions not derived from StandardError, it also means you
can't choose which exceptions are rescued: for example, you can't use the
rescue modifier to rescue a ZeroDivisionError but not an ArgumentError.

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de