lua-users home
lua-l archive

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


It was thus said that the Great Ivan once stated:
> Hello!
> 
> I’m trying to create my own type (for complex numbers) and use it within
> Lua scripts. It’s okay but the problem is that in some messages this type
> is denoted as ‘userdata’ which looks ugly. I have found that if type’s
> metatable has __name field, that it’s value is used as a type name.
> Unfortunately this key is not used everywhere, e.g. pairs(complex) still
> uses ‘userdata’ name. Is there a way I can make Lua to use custom type
> name?

  Try setting the __tostring() metamethod to print out how you want it to
look.  

> And a second question dedicated to the custom types. Say I have two arrays
> of luaL_Reg’s: _methods (instance methods) and _meta (metatable with magic
> methods). _methods array contains methods that are to be called for a
> particular instance and are used to manipulate it. _meta array contains
> metamethods (__add, __sub and so on). 

  It may not be clear in the manual, but use the following quite often
(example from
https://github.com/spc476/lua-conmanorg/blob/faf0780d01700a45e2af5d52f2c732fa45092c1e/src/fsys.c#L1180):

static const luaL_Reg m_dir_meta[] =
{
  { "__tostring"        , dir_meta___tostring   } ,
  { "__gc"              , dir_meta___gc         } ,
  { "rewind"            , dir_meta_rewind       } ,
  { "next"              , dir_meta_next         } ,
  { NULL                , NULL                  }
};

  luaL_newmetatable(L,TYPE_DIR);
#if LUA_VERSION_NUM == 501
  luaL_register(L,NULL,m_dir_meta);
#else
  luaL_setfuncs(L,m_dir_meta,0);
#endif

  lua_pushvalue(L,-1);
  lua_setfield(L,-2,"__index");

The luaL_Reg[] contains both methods and metamethods, and the __index field
of the metatable is set to itself so the regular methods can be found.  So:

> fsys = require "org.conman.fsys"

	loads the module

> dir = fsys.opendir(".")

	returns an instance of this type

> print(dir)
directory (0x7fb2c1501ac8)

	calls the __tostring() metamethod

> print(dir:next())
base64.c
> print(dir:next())
clock.c

	calls a method (next()) which is stored in the metatable.

> print(dir)
directory (0x7fb2c1501ac8)

	and just to show, another indirect call to __tostring()

  -spc (Does this solve your problem?)