lua-users home
lua-l archive

Re: ipairs in Lua 5.3.0-alpha

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


On 2014年8月18日 13:18:38 +0200
Jan Behrens <jbe-lua-l@public-software-group.org> wrote:
> Consider a function printcsv, which accepts a sequence:
> 
> function printcsv(seq, sep)
> sep = sep or ","
> for i, v in ipairs(seq) do
> if i > 1 then io.stdout:write(sep) end
> io.stdout:write(tostring(v))
> end
> io.stdout:write("\n")
> end
> 
> Calling this with a raw table is pretty much forward:
> 
> printcsv{"a", "b", "c"}
> -- prints:
> -- a,b,c
> 
> printcsv({"a", "b", "c"}, "; ")
> -- prints:
> -- a; b; c
This just got me to the idea that if ipairs is made to accept
functions (or even iterator triplets), we could also implement
a generic concat:
==================================================
function string.concat(sep, ...)
 local t = {}
 for i, v in ipairs(...) do
 t[i] = tostring(v)
 end
 return table.concat(t, sep)
end
==================================================
Or optimized in C:
==================================================
int poweriterator_concat(lua_State *L) {
 int sep = 0;
 luaL_Buffer buf;
 luaL_checkany(L, 2);
 if (lua_isnoneornil(L, 1)) {
 lua_pushliteral(L, "");
 lua_replace(L, 1);
 } else {
 luaL_checkstring(L, 1);
 }
 lua_pushcfunction(L, poweriterator_ipairs);
 lua_insert(L, 2);
 lua_call(L, lua_gettop(L) - 2, 3);
 lua_pushnil(L); // placeholder on stack at 5
 luaL_buffinit(L, &buf);
 while (1) {
 lua_pushvalue(L, 2); // func
 lua_pushvalue(L, 3); // state
 lua_pushvalue(L, 4); // pos
 lua_call(L, 2, 2);
 if (lua_isnil(L, -2)) {
 lua_pop(L, 2);
 break;
 }
 lua_replace(L, 5);
 lua_replace(L, 4);
 if (sep) {
 lua_pushvalue(L, 1);
 luaL_addvalue(&buf);
 } else {
 sep = 1;
 }
 luaL_tolstring(L, 5, NULL);
 luaL_addvalue(&buf);
 }
 luaL_pushresult(&buf);
 return 1;
}
==================================================
This would give us much more power than table.concat:
(","):concat{"a", "b", "c"}
-- evaluates to: "a,b,c"
string.concat("; ", assert(io.open("testfile", "r")):lines())
-- evaluates to:
-- "This is line #1 of my testfile.; This is line #2 of my testfile."
string.concat(",", pairs{apple=true, pear=true})
-- evaluates to:
-- pear,apple
-- (ordering may vary)
I would find that really useful and pretty much straightforward.
I also don't see any negative side effects of making ipairs accept
functions or iterator triplets. Are there any?
I can understand that some of you don't miss generic iterators. But
they would allow for a new style of programming when using Lua.
As I said, I don't see any cons, only pros.
Can anyone come up with a real con?
Regards
Jan

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