lua-users home
lua-l archive

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


On Sat, Aug 26, 2006 at 10:10:23AM -0700, Brian Segall wrote:
<snip> 
> test.lua:
> --------------------
> a = newstring("hello")
> b = newstring("hello")
> if a == b then
> 	print("they are equal")
> else
> 	print("they are not equal")
> end
> 
> 
> ----------------------
> 
> It always prints "they are not equal" since my comparison function is not 
> being called. luaO_rawequalObj in lobject.c is where the __eq methods are 
> determined to be different, and lacking a comparison handler Lua returns 
> false.

The manual states that

"'eq': the == operation. The function getcomphandler defines how Lua chooses a
metamethod for comparison operators. A metamethod only is selected when both
objects being compared have the same type and the same metamethod for the
selected operation."

And so your problem is that you don't have same metamethod for a and b in your
example above, since you create a new closure for CompareStrings in their
metatables. Check getmetatable(a).__eq and getmetatable(b).__eq.

One possible solution is to create a metatable, save it in the registry, and
use it for your newstrings. Somewhere in your module initialization
(luaopen_xxx), say

luaL_newmetatable(L, "newstring_mt");
lua_pushcfunction(L, CompareStrings);
lua_setfield(L, -2, "__eq");

Then, in newstring, instead of creating a new metatable and a new closure, do

- 	lua_newtable(L);
- 	lua_pushstring(L, "__eq");
- 	lua_pushcfunction(L, CompareStrings);
- 	lua_settable(L, -3);

+	lua_getfield(L, LUA_REGISTRYINDEX, "newstring_mt");

Check that now getmetatable(a).__eq == getmetatable(b).__eq, and your example
should work.

Cheers,
Luis.

-- 
A mathematician is a device for turning coffee into theorems.
        -- P. Erdos 

-- 
Luis Carvalho
Applied Math PhD Student - Brown University
PGP Key: E820854A <carvalho@dam.brown.edu>