lua-users home
lua-l archive

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




2009/11/9 Duncan Cross <duncan.cross@gmail.com>
On Mon, Nov 9, 2009 at 8:41 PM, liam mail <liam.list@googlemail.com> wrote:
> Duncan you are correct that in pushing the function twice they are not equal
> (checked using  lua_rawequal which seems strange); yet pushing the function
> once then using push_value whilst they are raw equal as you would expect
> still does not call the function.

My final observation in the code is another boolean/number problem
right at the end, when you get the result:

>        int result = lua_tointeger(s,-1);

...this should be lua_toboolean() instead. lua_tointeger() will return
0 for either boolean value.

-Duncan
 Yes another good catch, unfortunately the code I posted was to verify the result I was seeing using binding code which was pushing and pulling booleans. I feel this would not stop the function being called yet have adjusted the code and will inline it below for fullness.

struct Int_wrapper{int i;};

int equal(lua_State* s)
{
    Int_wrapper* i1 = static_cast<Int_wrapper *>( lua_touserdata(s, 1) );
    Int_wrapper* i2 = static_cast<Int_wrapper *>( lua_touserdata(s, 2) );
    lua_pushboolean(s, i1->i == i2->i ? 1 : 0 );
    return 1;
}
    void equal_userdataWithDifferentMetatables_returnsTrue()
    {
        lua_State* s = luaL_newstate();
        std::string chunk("equal = function (lhs, rhs) \
                          return lhs == rhs \
                          end");
        luaL_loadbuffer(s,chunk.c_str(),chunk.size(),"userChunk");
        lua_pcall(s,0,LUA_MULTRET,0);
        lua_getfield(s, LUA_GLOBALSINDEX, "equal");

        luaL_newmetatable(s, "mt1");
        int mt1 = lua_gettop(s);
        luaL_newmetatable(s, "mt2");
        int mt2 = lua_gettop(s);


        lua_pushcfunction(s, &equal);
        int func = lua_gettop(s);

        lua_pushliteral(s, "__eq");
        lua_pushvalue(s,func);
        lua_settable(s, mt1);

        lua_pushliteral(s, "__eq");
        lua_pushvalue(s,func);
        lua_settable(s, mt2);
        lua_remove(s,func);

        Int_wrapper* wrapper1 = static_cast<Int_wrapper*>(lua_newuserdata(s, sizeof(Int_wrapper)));
        int w1 = lua_gettop(*m_lua);
        lua_pushvalue(*m_lua,mt1);
        lua_setmetatable(*m_lua,w1);

        Int_wrapper* wrapper2 = static_cast<Int_wrapper*>(lua_newuserdata(s, sizeof(Int_wrapper)));
        int w2 = lua_gettop(s);
        lua_pushvalue(s,mt2);
        lua_setmetatable(s,w2);

        wrapper1->i = wrapper2->i = 1;
        lua_remove(s,mt1);
        lua_remove(s,mt2-1);

        lua_pcall(s,2,LUA_MULTRET,0);
        bool result = lua_toboolean(s,-1);
        CPPUNIT_ASSERT_EQUAL(true,result);
        lua_close(s);
    }