lua-users home
lua-l archive

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

2012/6/28 Egil Hjelmeland <>:

> Another recent suggestion was to let table.concat call tostring() for
> non-string array entries, which in turn may invoke __tostring meta method.
> Which is a concept my feeble mind can easily grasp.

That is exactly the effect of my patch plus this:

         function Concat(x,y) return tostring(x)..tostring(y) end
         getmetatable"".__concat = Concat

> What does the __concat concept offer that can not be done with
> __tostring on non-string entries?

It offers greater flexibility.  E.g. if instead of that second statement
you say:

         debug.setmetatable(false,{__concat = Concat})

only booleans get converted.

> (Sorry, I don't have time right now to play around with your patch.)
> Can it make table.concat return something else than a string?

Absolutely all it does is to make __concat do *literally* what it says
in the manual, i.e. evaluate

         table[i]..sep..table[i+1] ··· sep..table[j]   -- (1)

using concatenation.

BTW the manual is not quite correct — that expression reduces to
table[1] when #table==1, which may be a number, whereas (as you say)
table.concat always returns a string. The official Lua source code
actually evaluates the equivalent of

         ""..table[i]..sep..table[i+1] ··· sep..table[j]  -- (2)

by a method applicable only to table entries for which lua_isstring is

My patch can't make table.concat return anything that the concatenation
operator could not, except that it *could* return table[1] unchanged.
I'm willing to listen to an argument that the patch should do (2), not
(1), if accompanied by a request that the manual should be amended

> If yes, would it not be kind of surprise to feeble minded code readers?

If they are so feeble-minded, the fact that a..""..b could return
a non-string, with no call whatsoever to table.concat, would already
throw them off balance.

> Perhaps your case would be better served by a new function, something
> like table.aggregate(table), calling metamethod __aggregate, to warn
> readers that something interesting is going on?

If you want to keep the exact current behaviour available, a patch is
not the way to go. Rather put the new version into a module `xtable`,
which can also contain various other modifications of the table library,
such as a sort that returns the sorted table, other ways of computing
length (largest index in use, actual number of elements), etc. Then it's
as simple as

         table.concat = xtable.concat

to select the patched behaviour.