This post originated from an RSS feed registered with Agile Buzz
by James Robertson.
Original Post: The value of overriding
Feed Title: Cincom Smalltalk Blog - Smalltalk with Rants
Feed URL: http://www.cincomsmalltalk.com/rssBlog/rssBlogView.xml
Feed Description: James Robertson comments on Cincom Smalltalk, the Smalltalk development community, and IT trends and issues in general.
One of the really nice things about Smalltalk is the ability to replace any method in any class - there's no concept of "final" or sealed". Typically, it's better to subclass an existing class and add the new behavior there (or use delegation). However, that's not always practical. For instance, in BottomFeeder, I need to do HTTP queries (to get the XML files that make up feeds). VisualWorks has HTTP client libraries, and the libraries have an easy to use API. I soon realized that I was going to have to create a wrapper library, because it wasn't going to be sufficient to do:
response := HttpClient new get: 'http://www.somesite.com/feed.xml'.
There were a lot of things I needed to deal with:
Exceptions (Network errors, etc)
Permanent redirection (update the url silently)
Cookies
Authentication (and keeping track of username/password)
Conditional-Get
Compressed content
and tons of other small details. The HTTP client library in VW handles some of this, and wrapping it to provide the rest at an application level was easy enough. There came a point where I ran into a small problem though - I also use my wrapper library to handle POSTS from the blog tool that comes with BottomFeeder. Under some circumstances, an exception would be raised, and I'd have no access to the original HTTP response that was received - it had gotten nulled out by the library by the time my code got control again. Now, it's arguable that it shouldn't work that way, but hey - no library is perfect. Most developers aren't the Product Manager for the tool they end up using, so - unlike me - they can't go straight to engineering and ask questions. They have to go through support and maybe get a fix, someday. The nice thing about Smalltalk is that you can track down the issue yourself and deal with it in the meantime. I've removed numerous temporary hacks of this sort as the engineering team has dealt with them. Here's what I did in this case:
In the class HttpClient, there's a method #getResponse:. That's where the response is received from the server, before some post processing (and some of the exceptions raised here can result in the original response not being returned). Easy enough; I overrode the method, storing my version of it in an extension package that is part of my HTTP wrapper library. The part I overrode looks like this:
The only addition is the #originalResponse: call. I also added an instance variable to the class so that I could store that information somewhere. My wrapper library looks there in cases where it receives a nil response, so that it can better report the actual problem that was encountered. Was this critical? Maybe not - I suppose I could have gone with just reporting a generic failure and been done with it. The point is, I didn't have to - I had the option of fixing what I perceived to be a bug. Why else is that useful? Well, it's not always the case that things you report to support get dealt with the way you would like. Some are put on the back burner, some are rejected as "not bugs". The point is, being able to muck with all the code gives you the ability to route around that issue. Support doesn't believe you? Fine, you can fix it yourself. Support says it's a low priority? See the above. Support agrees that it's important, and says that it will be fixed in the next release? See the above.
With Smalltalk, your level of control over the situation is just higher. Now, do you want to start overriding the class libraries willy nilly? Of course not. This counts as a "power tool" - it's a really good and useful thing to have, but you want to be careful when you pull it off the shelf. The nice thing is, with Smalltalk, it's on the shelf, ready to be picked up at need