From: "Jesús Gabriel y Galán" Date: 2009-08-21T01:18:59+09:00 Subject: Re: extending ruby - handling errors On Thu, Aug 20, 2009 at 5:49 PM, Jason Lillywhite wrote: > I want to raise an ArgumentError, "Function only takes numeric objects." > if a non-numeric argument is passed to the existing Ruby method, > Numeric.ceil. > > #Here is my feeble attempt to extend Ruby: > > irb(main):001:0> class Numeric > irb(main):002:1>   alias :old_ceil :ceil > irb(main):003:1>   def ceil > irb(main):004:2>     raise ArgumentError, > irb(main):005:2*       "function only takes numeric objects." unless > self.is_a? Numeric > irb(main):006:2>     self.old_ceil > irb(main):007:2>   end > irb(main):008:1> end > => nil > > #But that does not work - I can't get past the call on the object > > irb(main):009:0> "foo".ceil > NoMethodError: undefined method `ceil' for "foo":String >        from (irb):9 > > Could someone point me in the right direction? Thank you. I'm not sure if what you are trying to achieve makes sense or not. The reason is that you don't want to check an argument to a method, you are trying to check that the *receiver* of the method call is of a certain type. And that cannot be done inside the Numeric.ceil or in my opinion it doesn't even make sense. Why? Because how do you know that String or any other object doesn't have a valid ceil method? In fact, when you call ceil on a string it's a completely different and unrelated method to ceil in any other class. For example, say I do this: class String def ceil "this is the ceil of #{self}" end end Then, I should be able to call "foo".ceil and you shouldn't be telling that that is wrong :-). On the other hand, if you want to check whether the method ceil can be called on a specific object, that can be checked using respond_to?: irb(main):001:0> "foo".respond_to? :ceil => false irb(main):002:0> 3.respond_to? :ceil => true But I'm not sure what you are trying to achieve, so I don't know if this is useful for you. On the other hand, if for some strange reason you want to convert NoMethodError into ArgumentError, you could try something like this (although I don't see any utility in this): irb(main):039:0> class Object irb(main):040:1> def method_missing meth, *args, &blk irb(main):041:2> raise ArgumentError, "#{meth} called on #{self.class}" irb(main):042:2> end irb(main):043:1> end => nil irb(main):044:0> "foo".ceil ArgumentError: ceil called on String from (irb):41:in `method_missing' from (irb):44 from :0 I mean, calling a non-existing method is not an ArgumentError, it's a NoMethodError :-) Hope this helps, Jesus.