Accessing object in rescue block

Hi,

when I rescue an exception, is there a way to access the object where
the exception was raised?

For example:

begin
  "something".nonexistent
rescue NoMethodError => e
  # here
end

In the rescue block, can I access the String "something"?

Best,
Florian

···

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

Not by default. According to http://www.ruby-doc.org/ruby-1.9/classes/Exception.html
an exception provides "...information about the exception—its type
(the exception’s class name), an optional descriptive string, and
optional traceback information..."

However the same page also says "...Programs may subclass Exception to
add additional information."

So, if your roll your own exceptions it's possible to add this
functionality.

class MyException < Exception

  attr_accessor :source

  def initialize(msg = nil, source = nil)
    super(msg)
    @source = source
  end
end

class Test
  def enclose(obj)
    if obj.kind_of?(String)
      "(#{obj})"
    else
      raise MyException.new('Enclose needs a string!', obj)
    end
  end
end

begin
  t = Test.new
  puts t.enclose('foo')
  puts t.enclose(5)
rescue MyException => err
  puts "Error: #{err.message}"
  puts "Source: #{err.source}"
end

Overriding the default Exception class might also be possible (after
all, it's ruby) but changing "default" behavior can be pretty risky as
well.

/lasso

···

On 28 Juli, 10:54, Florian Odronitz <o...@mac.com> wrote:

Hi,

when I rescue an exception, is there a way to access the object where
the exception was raised?

For example:

begin
"something".nonexistent
rescue NoMethodError => e
# here
end

In the rescue block, can I access the String "something"?

Best,
Florian
--
Posted viahttp://www.ruby-forum.com/.

There is no way I am aware of which allows for fetching the instance from the NoMethodError if this is what you want. If you display the exception you will see a textual description probably derived from #inspect:

irb(main):001:0> begin
irb(main):002:1* "".foo
irb(main):003:1> rescue Exception => e
irb(main):004:1> puts e.display
irb(main):005:1> end
undefined method `foo' for "":String
=> nil
irb(main):006:0>

If that is not sufficient for you, you can reference a variable defined after "begin":

irb(main):006:0> begin
irb(main):007:1* x = ""
irb(main):008:1> x.foo
irb(main):009:1> rescue Exception => e
irb(main):010:1> p x
irb(main):011:1> end
""
=> ""
irb(main):012:0>

Kind regards

  robert

···

On 28.07.2010 10:54, Florian Odronitz wrote:

when I rescue an exception, is there a way to access the object where
the exception was raised?

For example:

begin
   "something".nonexistent
rescue NoMethodError => e
   # here
end

In the rescue block, can I access the String "something"?

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Thanks for your thoughts, I figured it out.

I was coming from this Article:
http://rbjl.net/26-the-28-bytes-of-ruby-joy

The author suggests to let the method_missing of Nil always return nil
so you could do things like:
some_object.this_is_null.do_something_more
would return nil and not raise on the undefined method
'do_something_more' on nil.
I thought such an approach was to intrusive and it would be better to do
something like:

ignore_nil{some_object.this_is_null.do_something_more}

My current implementation looks like this:

class NoMethodErrorInNil < NoMethodError; end

class NilClass
  def method_missing(method_name, *args)
    raise NoMethodErrorInNil, "undefined method `#{method_name}' for
nil:NilClass"
  end
end

class Object
  def ignore_nil(return_value = nil, &block)
    begin
      yield
    rescue NoMethodErrorInNil => e
      return return_value
    end
  end
end

···

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