将 __call 元方法作为迭代器
Make __call metamethod as iterator
我正在尝试从其他应用程序的脚本中模拟某些功能的执行。该应用程序有 Lua 库,其中包含函数 list()
,它 returns table 其中键是字符串 UUID,值只是字符串,如 local tbl = { "0000..-0000-..." = "someString", etc... }
。那个table可以在for循环中迭代,比如
local lib = require("someLibrary.lua");
for key, value in lib.list() do
-- do something with keys and values, like print
end
-- or it can be used like this
local tbl = lib.list();
for key, value in tbl do -- tbl works as pairs(tbl) and works exactly how code on top
-- do something with keys and values, like print
end
所以问题是,我如何实现 __call 元方法以作为 pairs() 或 next() 等工作?
谢谢
pairs(tbl)
returns next,tbl,nil
.
也一样
setmetatable(tbl,{__call=function (t) return next,t,nil end})
然后你可以写
for key, value in tbl() do
print(key, value)
end
我认为你无法避开那里的 ()
。
是的!我设法找到了我的问题的答案。我找到了我试图复制的库的源代码。它实际上使用局部变量来遍历 table
这是我如何使 lib.list()
和 lst
工作的代码
function lib.list(filter, exact)
if filter == nil then filter = '' end;
if exact == nil then exact = false end;
local list = Component.list(filter, exact); -- just gets table from app that written in C#, treat like someClass.getSomeTable()
local list_mt = {}; -- metatable that assigns to above "list" table
local key = nil; -- key that will be used in iterator
function list_mt.__call() -- __call metamethod for "list" table
key = next(list, key);
if key then
return key, list[key]
end
end
return setmetatable(list, list_mt); -- return table with assigned metatable that contains __call metamethod
end
我正在尝试从其他应用程序的脚本中模拟某些功能的执行。该应用程序有 Lua 库,其中包含函数 list()
,它 returns table 其中键是字符串 UUID,值只是字符串,如 local tbl = { "0000..-0000-..." = "someString", etc... }
。那个table可以在for循环中迭代,比如
local lib = require("someLibrary.lua");
for key, value in lib.list() do
-- do something with keys and values, like print
end
-- or it can be used like this
local tbl = lib.list();
for key, value in tbl do -- tbl works as pairs(tbl) and works exactly how code on top
-- do something with keys and values, like print
end
所以问题是,我如何实现 __call 元方法以作为 pairs() 或 next() 等工作?
谢谢
pairs(tbl)
returns next,tbl,nil
.
也一样
setmetatable(tbl,{__call=function (t) return next,t,nil end})
然后你可以写
for key, value in tbl() do
print(key, value)
end
我认为你无法避开那里的 ()
。
是的!我设法找到了我的问题的答案。我找到了我试图复制的库的源代码。它实际上使用局部变量来遍历 table
这是我如何使 lib.list()
和 lst
工作的代码
function lib.list(filter, exact)
if filter == nil then filter = '' end;
if exact == nil then exact = false end;
local list = Component.list(filter, exact); -- just gets table from app that written in C#, treat like someClass.getSomeTable()
local list_mt = {}; -- metatable that assigns to above "list" table
local key = nil; -- key that will be used in iterator
function list_mt.__call() -- __call metamethod for "list" table
key = next(list, key);
if key then
return key, list[key]
end
end
return setmetatable(list, list_mt); -- return table with assigned metatable that contains __call metamethod
end