[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: table.concat and metamethods
- From: Dirk Laurie <dirk.laurie@...>
- Date: Thu, 28 Jun 2012 11:35:50 +0200
2012/6/28 Egil Hjelmeland <privat@egil-hjelmeland.no>:
> 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
true.
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
likewise.
> 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.
Dirk