When is it okay to reopen NilClass?
I just read a post advocating changing NilClass#method_missing to always return nil. Their argument is that you no longer have to check if you actually have something before calling methods on it like:
@sun && @sun.still_burning? Instead, you could just call @sun.still_burning?, which is nice. I usually just check isthesunstillburning.com 20 times a day to make sure, but you get the point.

Now, it’s a very attractive, very short solution to an every day annoyance—that alone is enough to make me worry. Overriding #method_missing on NilClass just seems wrong. The better solution is to define Null Objects for all of your classes, and have those returned instead of nothing. Yeah, it’s more work than the method_missing solution, but it’s a lot safer and doesn’t leave such a bad taste in my mouth.
I do actually reopen NilClass though.
Often, actually. Working with rspec and making typos can be very frustrating otherwise. If do @sum.should_recieve(:set) instead of @sun, then you’ll get
Mock 'some mock' received unexpected message :tyop?
# or
Mock 'NilClass' expected :list_pathways with ("hsa") once, but received it 0 timesThe second one is easy to realize you have a typo, sure. But I know I’ve wasted time wondering why the expectation failed, and I’m sure you have too. By adding a few methods to NilClass, this is no longer an issue:
class NilClass
def should_receive(*args)
raise "WARNING: you tried to add expectations to nil!"
end
alias :stub! :should_receive
endWARNING: you tried to add expectations to nil!When else have you found it okay to mess around with NilClass?
I’m sure there are a few other occasions where it makes sense.
Sun picture from rodger smith, flickr
Trackbacks
Use the following link to trackback from your own site:
http://blog.bitfission.com/trackbacks?article_id=when-is-it-okay-to-reopen-nilclass&day=04&month=03&year=2008
about 18 hours later:
Check out the andand project. It will let you do this explicitly, without messing up your expectations of how NilClass works.
Ruby already has enough cleverness built in.