rubymethod-missing

Throw custom exception in `method_missing` without calling .new


I'm redefining method_missing for a proxy-style object. I would like to be able to throw a custom NoMethodError (or some other error if NoMethodError is a particular problem, I used an ArgumentError below) to give the caller more information as to why the particular proxy object doesn't have the method.

However, when I try to throw any exception from method_missing I get into a recursive loop that eventually results in SystemStackError: stack level too deep.

I would like to be able to do something like this:

class X
  define method_missing(symbol, *args)
    raise ArgumentError("Here: #{symbol} ")
  end
end

x = X.new
x.a # Raise an ArgumentError, not a SystemStackError

Solution

  • I don't think you can raise an exception by calling the exception class as a method like that. It can't find a method named ArgumentError so it tries calling your method_missing to see if you can handle it, then you try calling it again, and the cycle repeats (try it in a fresh irb session without your code loaded, you'll see it raises a NoMethodError).

    I believe the most popular way to throw an exception would be 2 parameters to raise:

    raise ArgumentError, "Here: #{symbol}"
    

    although if you want to be a bit more explicit you can also pass in an instance of the exception class:

    raise ArgumentError.new("Here: #{symbol}")