Today I was trying to find how to properly override Ruby standard Exception. To my surprise, I was not able to find any tutorial or even paragraph about it. No recommendations, no design patterns. Everything was the same:
class MyError < StandardError; end
As a Java guy, I tend to encapsulate lots of things into Exceptions. It's not a bad thing, actually it is a good thing. So I asked myself - what should I override, how, and why?
Let's skip the general Ruby recommendation to override StandardError instead Exception. Different class, the very same interface. To my surprise again, both Exception and StandardError classes are defined in the Ruby C code.
So I have rewritten the Ruby Exception into this Ruby code. Please note I made my life a little easier and some of the methods do not return the exact output as Ruby does (e.g. inspect), but we get very good overview with it. Please note this is Ruby 1.8, there is one small change in 1.9 in regard to method to_str, but it makes no difference for us.
@mesg = msg
@bt = nil
return self.class.name if @mesg.nil?
alias :message :to_s
alias :to_str :to_s
@bt = bt
return self if msg == message
I think the code says it all. Now we can see what we actually need to redefine. Now, let's do a small example.
class MyError < StandardError
def initialize(msg, my_additional_info = "")
info = my_additional_info
As you can see from the Exception code, Ruby stores the message into instance variable called "mesg". Since this is native code, we are not able to access it. The only way to get it is to call to_s method. Please do not do this:
This will end up with stack overflow. Special thanks to Ivan Nečas for helping me with this.
I have to admit this interface is not the best feature of Ruby. I can imagine an accessor for the message itself. And with a different name than "mesg". But that is life.
Nobody told us Ruby programming's gonna be easy. Take care.