lua-users home
lua-l archive

Re: table.concat and metamethods

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


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

AltStyle によって変換されたページ (->オリジナル) /