lua-users home
lua-l archive

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


I've made a little more progess on getting better error reporting when
overriding __newindex. If I implement my __newindex in C instead of lua
I can better control the error that is reported. Take the following code
as an example -

static int SetValue( lua_State* L )
{
  MyObject* obj = *(MyObject**)luaL_checkudata(L,1, MyObjectClass);;
  double val = luaL_checknumber(L,2);
  std::cout << "SetValue " << val << std::endl;
  if( val > 10 ) 
  {
    luaL_error(L, "value too big");
  }
  obj->value = val;
  return 0;
}

static const struct luaL_reg MyObjectInstanceMethods[] = 
{
  { "SetValue", SetValue },
  {NULL,NULL}
};

static int NewIndex( lua_State* L )
{
  MyObject* obj = *(MyObject**)luaL_checkudata(L,1, MyObjectClass);
  std::string key = luaL_checkstring(L,2);
  if( key == "Value" )
  {
    double value = luaL_checknumber(L,3);
    if( value > 10 )
    {
      lua_pushstring(L,"value too big");
      lua_error(L);
    }
    obj->set_value(value);
  }
  return 0;
}

int luaMyObjectOpen( lua_State* L )
{
  luaL_newmetatable( L, MyObjectClass );
  lua_pushvalue(L, -1);
  lua_pushvalue(L, -1);
  // normal index
  lua_setfield(L, -2, "__index");
  luaL_register( L, NULL, MyObjectInstanceMethods );
  // __newindex
  lua_pushcfunction(L, NewIndex);
  lua_setfield(L, -2, "__newindex");
  luaL_openlib(L, "Object", ObjectLibMethods, 0);
  return 0;
}

The goal is that if a user specifies a value greater than 9, an error
should be raised. If the user uses the SetValue function directly, I get
exactly the error reporting I desire-

	obj = Object.New()
	obj:SetValue(12)
	-----------
	test.lua:2: value too big

But if I use the __newindex interface to set the value, I don't get the
line number

	obj = Object.New()
	obj.Value = 12
	-----------
	value too big

When I raise the error inside my NewIndex function, is there a way to
get the current line number from the script being executed so it acts
the same as the :SetValue() call?