I have this bit of code:
m = board.method(cmd)
begin
m.call(p, *args)
rescue ArgumentError => err
p.notify "Too many arguments to command '#{cmd}'."
end
The “rescue ArgumentError” is meant to catch it if I tried to call the
method with too many arguments, because *args is user input that may
be invalid.
However, if m.call(p, *args) succeeds, but there’s a bug inside that
method that generates an ArgumentError, then the rescue also catches
it. (I don’t want to catch it; I want it to crash so that I’ll see
where the bug is. Dead Programs Tell No Lies.)
Would it be possible to:
- Check how many arguments the method wants without actually calling
it,
or
- Make the rescue only apply to the m.call.
I don’t think #1 is possible; there is a Method#arity method, but if
the method takes a variable number of arguments, Method#arity only
tells me the minimum number of arguments, not the maximum number. For
example, take this function:
irb(main):004:0> def something(arg1, arg2, arg3=nil, arg4=nil); end
nil
irb(main):005:0> method(:something).arity
-3
This tells me the method needs at least 3 arguments. But it doesn’t
tell me that the method will not accept more than 4 arguments.
As for #2, I think I might be able to look at err.backtrace[0] and
make sure that it mentions the name of the method that I just called.
That seems like a dirty way of doing it, though (but I can’t think of
anything else).