Saturday, May 13, 2006

Don't Get Me Wrong...

I actually like Ruby, I really do. It's become my favourite language for programming at home. One major annoyance I ran into today though has to do with the way booleans are implemented. The number 0 is evaluated as true. So the following actually prints!

my_var = 0
if (my_var)
printf("my_var evaluated as true?!")
end

As long as you're in the world of pure Ruby, this is ok, since you should really be writing 'my_var = false' anyway so the if statement behaves. However, databases generally implement booleans as ints. In fact, if you declare a field as a boolean in mysql, it really just creates a tinyint in the background. When you set that field to false in Rails, it ends up being set to '0' in the database, and then when you evaluate it in a condition, it behaves very unexpectedly, even though in the code, it really is being set to 'true'. You have to use the '?' operator to resolve the problem, e.g.

if (my_active_record_object.flag_set?)
printf("This works as expected\n")
end

if (my_active_record_object.flag_set)
printf("This doesn't work as expected at all!\n")
end

It's a very insidious problem... This is one of those cases where I just kind of mentally shrug... WTF indeed!

No comments: