Using inline "rescue" with error class

Hi, instead of:

···

----------
begin
  IPAddr.new(value)
rescue ArgumentError
  puts "Invalid IP"
end
----------

I would like to just write:
  IPAddr.new(value) rescue ArgumentError puts "Invalid IP"

Unfortunatelly it doesn't work when the rescue action occurs:
------------
Invalid IP
NoMethodError: undefined method `ArgumentError' for main:Object
------------

Do I miss some way to set the error class when using inline rescue?

Thanks a lot.

--
Iñaki Baz Castillo

The rescue statement modifier doesn't take an exception parameter.
You'd have to make do with:
IPAddr.new(value) rescue puts "Invalid IP"

This of course makes the construct much less appealing.
There has been a very recent thread related to this.

Solidarity,
lasitha

···

On Tue, Mar 3, 2009 at 5:58 AM, Iñaki Baz Castillo <ibc@aliax.net> wrote:

I would like to just write:
IPAddr.new(value) rescue ArgumentError puts "Invalid IP"

Unfortunatelly it doesn't work when the rescue action occurs:
------------
Invalid IP
NoMethodError: undefined method `ArgumentError' for main:Object
------------

lasitha wrote:

I would like to just write:
�IPAddr.new(value) rescue ArgumentError puts "Invalid IP"

Unfortunatelly it doesn't work when the rescue action occurs:
------------
Invalid IP
NoMethodError: undefined method `ArgumentError' for main:Object
------------

The rescue statement modifier doesn't take an exception parameter.
You'd have to make do with:
IPAddr.new(value) rescue puts "Invalid IP"

... which rescues StandardError and all subclasses.

However you probably wouldn't want to do this:

  addr = IPAddr.new(value) rescue puts "Invalid IP"
  do_something_with(addr)

because the second line would get addr equal to nil, and further errors
would occur. One solution is just to let the ArgumentError propagate
upwards, because the exception message already says "invalid address":

irb(main):002:0> IPAddr.new("x")
ArgumentError: invalid address

Having said that, sometimes I do like to include the offending value in
error messages, so I can end up writing stuff like

  begin
    addr = IPAddr.new(value)
  rescue ArgumentError
    raise ArgumentError, "Invalid IP address #{value.inspect}"
  end

The risk here is that if the user provides an arbitrarily long string,
you'll get an arbitrarily long exception message too.

Another option is to stick rescue clause(s) at the end of a method body,
because you don't need a 'begin'.

  def foo(value)
    addr = IPAddr.new(value)
    do_something_with(addr)
  rescue ArgumentError
    puts "Invalid IP address"
    raise # or not, it's up to you
  end

On the plus side, this prevents the nil addr being used. On the minus
side, *any* ArgumentError in the body of foo or any of the methods it
calls will be reported as "Invalid IP address"

Regards,

Brian.

···

On Tue, Mar 3, 2009 at 5:58 AM, I�aki Baz Castillo <ibc@aliax.net> wrote:

--
Posted via http://www.ruby-forum.com/\.

Thanks for so good explanation.

···

El Martes, 3 de Marzo de 2009, Brian Candler escribió:

lasitha wrote:
> On Tue, Mar 3, 2009 at 5:58 AM, I�aki Baz Castillo <ibc@aliax.net> wrote:
>> I would like to just write:
>> �IPAddr.new(value) rescue ArgumentError puts "Invalid IP"
>>
>> Unfortunatelly it doesn't work when the rescue action occurs:
>> ------------
>> Invalid IP
>> NoMethodError: undefined method `ArgumentError' for main:Object
>> ------------
>
> The rescue statement modifier doesn't take an exception parameter.
> You'd have to make do with:
> IPAddr.new(value) rescue puts "Invalid IP"

... which rescues StandardError and all subclasses.

However you probably wouldn't want to do this:

  addr = IPAddr.new(value) rescue puts "Invalid IP"
  do_something_with(addr)

because the second line would get addr equal to nil, and further errors
would occur. One solution is just to let the ArgumentError propagate
upwards, because the exception message already says "invalid address":

irb(main):002:0> IPAddr.new("x")
ArgumentError: invalid address

Having said that, sometimes I do like to include the offending value in
error messages, so I can end up writing stuff like

  begin
    addr = IPAddr.new(value)
  rescue ArgumentError
    raise ArgumentError, "Invalid IP address #{value.inspect}"
  end

The risk here is that if the user provides an arbitrarily long string,
you'll get an arbitrarily long exception message too.

Another option is to stick rescue clause(s) at the end of a method body,
because you don't need a 'begin'.

  def foo(value)
    addr = IPAddr.new(value)
    do_something_with(addr)
  rescue ArgumentError
    puts "Invalid IP address"
    raise # or not, it's up to you
  end

On the plus side, this prevents the nil addr being used. On the minus
side, *any* ArgumentError in the body of foo or any of the methods it
calls will be reported as "Invalid IP address"

--
Iñaki Baz Castillo