Friday, January 30, 2009

Variable Naming Matters!

I woke up this morning with a production bug on my plate. Those of you who read this blog regularly probably know that one of the startups I'm working on is a medicaid billing software suite for school districts. The problem I was having was that there were some transactions being added to our billing batches that shouldn't have been. See, in order to bill a transaction to medicaid, several things must be in place: the student must have a prescription, the therapy provided must be one of the federally approved therapies, the therapist must have a federally issued NPI number on file, etc.

These transactions were failing validation, obviously, because they were invalid. They should never have been billed in the first place. When I dug into my code, I couldn't see the problem, although based on the title of this post you will probably see it immediately:

def get_student_detail(s)
group = s.appts.select{|sa| s.is_medicaid_eligible}
if group.size > 0
claim = Claim.new(group,{:batch_id=>self.id})
end
end


I spent a lot of time on this. I wrote more unit tests, couldn't figure out why they were failing. I built mocks and tested many underlying methods to prove that they were working properly. Eventually the only way I figured it out was when I kicked up an "irb" session on my production box and started stepping through this code one piece at a time. what an embarrassment when I realized what I had done.

Yes, I went and named my "student" object instance "s". And then I named my "StudentAppointment" object instance "sa". And they both have a method called "is_medicaid_eligible" that returns a boolean value. So, if the student is eligible, all his appointments get billed regardless of whether those appointments are eligible or not, because I mistakenly wrote "s" instead of "sa" in the block on line 2 of the above code. There are plenty of arguments out there about naming conventions and whether they really matter, and I may not be qualified to participate in many of them, but here's one lesson I won't soon forget:

if I had used the name "student" for my student variable, and "appointment" for my appoitment variable, I probably wouldn't have spent an hour trying to find this bug.

1 comment:

Ben said...

What I do when I need to come up with local variable names for two things that start with the same letter is make them start with different letters. I probably would have picked s for the student variable and a for the student appointment variable. Less easy to write a bug, and even more terse.

I think the problem is similar variable names. One way to make them less similar is to make them longer; another way is to make it so they don't start with the same letters.