lua-users home
lua-l archive

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


In my opinion (and the opinion of various denizens of lua-l and #lua)
there is a serious flaw in Lua 5.1's new # operator.

Specifically it is that it does not invoke the __len metamethod on
tables, only on userdata.

This results in an inability to do interesting things with the #
operator on objects implemented in pure lua. Consider a special
sparse-array as a critical example -- the default implementation of # on
a table (luaH_getn) clearly will never work reliably on a sparse array.
But if the __len metamethod were checked for on tables also, then it
would clearly allow for the implementor to sort it out.

I know this has external effects on the language and that this late in
the game this is frowned upon, but honestly I thought it was a mistake
in the beta and would have been corrected before the release candidate.

It's fairly easy to replace the chunk in lvm.c for handling OP_LEN for
tables to be something like:

          case LUA_TTABLE: {
            const TValue *tm = luaT_gettmbyobj(L, rb, TM_LEN);
            if (ttisnil(tm)) {
              setnvalue(ra, cast(lua_Number, luaH_getn(hvalue(rb))));
            } else {
              Protect(callTMres(L, ra, tm, rb, &luaO_nilobject));

And such would save a lot of hassle and prevent us from having another
second-class metamethod to go alongside __gc.

I appreciate that the docs may need tweaking as a result of this, but I
seriously recommend it be done. Otherwise I can see many distributions
applying such a patch as a "bugfix" which will make varying and
effectively incompatible versions of Lua occupy our distributions.


Daniel Silverstone               
PGP mail accepted and encouraged.            Key Id: 2BC8 4016 2068 7895