Context of an Error

I feel like I should know how to do this already, but... How do I get
the context in which an error was thrown?

  x = SomeClass

  def dosomething
    x.bar
  end

  begin
    dosomething
  rescue NoMethodError
    p e.context #=> SomeClass (HOW?)
  end

Thanks,
T.

but, imho, that's not the context. the context would be 'dosomething' ? can
you explain what you mean by 'context'? if by context you mean the object
raising the NoMethodError, you can do obviously hook into method_missing to
make it add this info to every execption, otherwise this is all you've got:

   harp:~ > cat a.rb
   class C; end

   begin
     C.foobar
   rescue NoMethodError => ne
     (NoMethodError.instance_methods - Object.instance_methods).sort.each do |m|
       p m => ne.send(m)
     end
   end

   harp:~ > ruby a.rb
   {"args"=>}
   {"backtrace"=>["a.rb:4"]}
   {"exception"=>#<NoMethodError: undefined method `foobar' for C:Class>}
   {"message"=>"undefined method `foobar' for C:Class"}
   {"name"=>:foobar}
   a.rb:7:in `set_backtrace': wrong number of arguments (0 for 1) (ArgumentError)
           from a.rb:7
           from a.rb:6

so, other than scraping that info - which does contain what you want - i think
adding an attr to Exception and making method_missing set it on the way out
might be the only way to go...

cheers.

-a

···

On Wed, 4 Oct 2006, Trans wrote:

I feel like I should know how to do this already, but... How do I get
the context in which an error was thrown?

x = SomeClass

def dosomething
   x.bar
end

begin
   dosomething
rescue NoMethodError
   p e.context #=> SomeClass (HOW?)
end

Thanks,
T.

--
in order to be effective truth must penetrate like an arrow - and that is
likely to hurt. -- wei wu wei

I don't know if there is a builtin way but:
class Object
  alias lmc_ruby_raise raise
  def raise(*args)
    if args.length >= 2
      # class + some args
      klass, *rem_args = args
      exp = klass.new(*rem_args)
      exp.instance_variable_set("@context", self.class)
      lmc_ruby_raise(exp)
    elsif args.length == 1
      case args[0]
      when Class
        exp = args[0].new
        exp.instance_variable_set("@context", self.class)
        lmc_ruby_raise( exp )
      when String
        exp = RuntimeError.new(args[0])
        exp.instance_variable_set("@context", self.class)
        lmc_ruby_raise( exp )
      else
        exp = args[0]
        exp.instance_variable_set("@context", self.class)
        lmc_ruby_raise( exp )
     end
   end
end
end

class Exception
  attr_reader :context
end

Totally untested of course.

···

On Wed, Oct 04, 2006 at 10:50:05PM +0900, Trans wrote:

I feel like I should know how to do this already, but... How do I get
the context in which an error was thrown?

  x = SomeClass

  def dosomething
    x.bar
  end

  begin
    dosomething
  rescue NoMethodError
    p e.context #=> SomeClass (HOW?)
  end

Thanks,
T.

I don't know if there is a builtin way but:
class Object

Perhaps this should be
   module Kernel

since that's where raise actually lives.

Totally untested of course.

ditto

···

On 10/4/06, Logan Capaldo <logancapaldo@gmail.com> wrote:

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

>I don't know if there is a builtin way but:
>class Object

Perhaps this should be
  module Kernel

since that's where raise actually lives.

Well actually if I put it in Object and raise is defined in Kernel that
would simplify my code. No need for an alias, just use super

···

On Thu, Oct 05, 2006 at 10:27:33PM +0900, Rick DeNatale wrote:

On 10/4/06, Logan Capaldo <logancapaldo@gmail.com> wrote:

>Totally untested of course.

ditto

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/