Finding bugs with irb

There has been a "lot": of "irb": "love": happening lately, and I'm lovin' the irb, too.

After launching a Rails e-commerce application recently, I was taking a look through the database just to make sure things were working as expected. Lo and behold, I found a problem. Something funky was happening with a small number of the orders. Time to dig in.

The problem centered around calculating discounts, which calculations can be affected by a number of variables present at the time of checkout: the particular items in the cart, the discount code used, etc. In other words, it would be somewhat difficult to work out what should have happened versus what actually happened by taking the relevant data and doing the calculations by hand. In this case, it would be much easier to actually poke at the transactions in question and play with the code as it would have interacted at the time of the transaction. Rails console to the rescue!

$ ./script/console >> irb Sale.find(:first, :conditions => "something's not quite right") >>

What's that you say? Invoking irb from inside irb? Madness! What does it do? It loads another session inside your current session, and now @self@ points to the results of that @Sale.find@. Why is this so useful? Well, suppose you have an instance method in the Sale class that does a lot of calculations, pulling in the related discount, related line items, etc., and it has references to @self.this@ and @self.that@ all over the place in there. With a little help from this irb sub-session, now you can play with that code as it was written, and (in this case) as it was executed against the instance when the instance was first created.

So, with this powerful tool in hand, and a little time poking at the discount calculations, I found my problem, wrote a test that reproduced it, fixed it, and repaired the affected transactions. Yay irb!