Can you spot the bug?

In a model class which has 'quantity', 'quantity_already_taken' and 'quantity_requested' properties, I add the following:

def before_save
  quantity = 1 if quantity == 0
  if quantity + quantity_already_taken > quantity_requested
  ......

Tests blow up everywhere with:

TypeError: nil can't be coerced into Fixnum   (on the line with the addition)

Why?

After a little more debugging, it is clear that 'quantity' is nil. How could that happen?

The answer lies in the fact that Ruby requires an explicit self reference when using attribute writers (aka, property setters) within the class itself. This feels clunky to me, but for your information, here's a rationalisation of the explicit self requirement.

So, in case you're wondering, what happened above is that the 'if' line created a nil local variable called 'quantity'! This local variable then had higher scope precedence than the class attribute with the same name. The addition line was then using the local 'quantity' rather than the class attribute and hence failed with the nil error.

All fixed by explicity referencing self:

def before_save
  self.quantity = 1 if (quantity == 0)
  if quantity + quantity_already_taken > quantity_requested
  ......

Actions

Information