当块函数返回nil时load()的行为

时间:2013-06-05 20:19:34

标签: lua lua-5.1

来自Lua 5.1 documentation for load()

  

使用函数func加载一个块来获取它的碎片。每次调用func都必须返回一个与之前结果连接的字符串。返回一个空字符串 nil ,或者没有值表示该块的结尾。

从我的测试来看,这实际上并非如此。或者说,文档至少具有误导性。

考虑这个示例脚本:

function make_loader(return_at)
    local x = 0

    return function()
        x = x + 1

        if x == return_at then return 'return true' end

        return nil
    end
end

x = 0
repeat
    x = x + 1
until not load(make_loader(x))()

print(x)

输出是在make_loader()放弃之前返回nil的{​​{1}}返回的函数的连续调用次数,并返回一个不返回任何内容的函数。

如果要以面值获取文档,可以预期此处的输出为“1”。但是,输出为“3”。这意味着在load()放弃之前,load()的参数被调用,直到它返回nil 三次

另一方面,如果chunk函数立即返回一个字符串,然后在后续调用中返回load(),则只需要一个nil来停止加载:

nil

按照我的预期打印“2”。

所以我的问题是:文档错了吗?出于某种原因,这种行为是否可取?这只是function make_loader() local x = 0 return { fn=function() x = x + 1 if x == 1 then return 'return true' end return nil end, get_x=function() return x end } end loader = make_loader() load(loader.fn) print(loader.get_x()) 中的错误吗? (这似乎是故意的,但我找不到任何解释原因的文件。)

2 个答案:

答案 0 :(得分:6)

这是5.1中的错误。它已在5.2中得到纠正,但我们未能将修正纳入5.1。

答案 1 :(得分:3)

我得到的结果与你的结果略有不同,但它们仍然不是文档所暗示的结果:

function make_loader(return_at)
    local x = 0
    return function()
        x = x + 1
        print("make_loader", return_at, x)
        if x == return_at then return 'return true' end
        return nil
    end
end

for i = 1, 4 do
    load(make_loader(i))
end

返回以下结果:

make_loader 1   1
make_loader 1   2
make_loader 2   1
make_loader 2   2
make_loader 2   3
make_loader 3   1
make_loader 3   2
make_loader 4   1
make_loader 4   2

对于1,它被调用了两次,因为第一个是return true而第二个是零。对于2,它被调用了三次,因为第一个是nil,然后是return true,然后是nil。对于所有其他值,它被调用两次:似乎忽略了第一个nil,并且至少再次调用该函数。

如果情况确实如此,那么文档需要反映出来。我查看了源代码,但没有看到任何可以解释为什么第一个返回的nil被忽略的东西(我也用空字符串测试,没有相同结果的值)。