lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

I had a strange bug in my code and the fix surprised me. In the spirit of extracting value from failure, I thought I'd share what I had found...

I have an object that represents a url. I want to be able to know when two instances are the same value, so I defined the `__eq` metamethod[1]

My object design needs a unique metatable for each object. Not thinking too deeply upon "same metamethod for eq"  limitation, I defined __eq inside each new object's metatable. The definition is:

__eq = function(a, b) return a.url == b.url end

When running "tests" at the bottom of the file in which the module is written, I always got what I expected. Two objects that held the same values were compared as equal, as I wanted. I ran the test in a for loop 10,000 times and it always ended up with the same result.

I ran the test inside of busted[1] and roughly 1 in 4 attempts would fail, with the __eq operation not getting called. As I dug deeper, I saw that in the failure case, the functions were unique and that's why things didn't work. 

I'm sure that there are excellent reasons for enforcing that the two objects have the same function and are the same type, but this experience felt like debugging threads in C.


[1] "eq": the == operation. The function getequalhandler defines how Lua chooses a metamethod for equality. A metamethod is selected only when both values being compared have the same type and the same metamethod for the selected operation, and the values are either tables or full userdata.