Search code examples
stringfunctionlualoadchunks

What does `load` do with chunk as function in Lua


There is load function that compiles chunk if chunk is string. But i don't understand, what does it do with function.

They said:

If chunk is a function, load calls it repeatedly to get the chunk pieces. Each call to function must return a string that concatenates with previous results. A return of an empty string, nil, or no value signals the end of the chunk.

but i can't find examples about it.


Solution

  • Often you have a "stream" of strings - think chunks of a file, or from a socket - and want to pass them directly to Lua to lex, parse and emit bytecode.

    Usually, the bottleneck here will be the I/O, not the CPU. You want to pass those chunks directly to Lua so that you can effectively parallelize waiting for the next chunk while Lua gets started loading.

    It also saves memory usage: You don't have to build a temporary table of strings (or even worse, doing repeated string concatenation) to concatenate your chunks to a single string to pass to loadstring; you can directly pass the chunks you get to Lua.

    So here's a simple implementation of dofile in terms of load (ignoring filename = nil for simplicity):

    function dofile(filename)
        local file <close> = io.open(filename)
        assert(load(function() return file:read(1024) end, filename))()
    end
    

    This reads file in chunks of 1024 bytes, passing them to Lua to load. assert is used to ensure that the loading was successful (no syntax errors). Then the chunk is executed.

    As another example, here's a weird way to write "Hello World!" using load:

    local t = {"print", '("', "Hello World!", '")'}
    local i = 0
    local function next_chunk()
        i = i + 1
        return t[i] -- `nil` if `i` is out of bounds
    end
    assert(load(next_chunk))()