Unable to import the module with Lua, the results try to index the global "test" (a null value)

advertisements

Without success I have attempted to import my own Lua files into other scripts using the require keyword but whenever I attempt to call any functions contained within the imported module (e.g. "test.lua") I reach the subsequent error:

require 'test'
test.method(args)
==> yields error:
==> Attempt to index global 'test' (a nil value)

I've added the file to the package.path in case this was the issue, but again there was no beginning error indicating that it cannot find the file in Lua's pathway.

package.path = package.path .. ";/path/to/test.lua"
require 'test'
test.method(args)
==> yields error:
==> Attempt to index global 'test' (a nil value)

I'm running an interactive Lua shell from the directory where the file is. When attempting to print the local variable name, e.g. local test = require "test" the value is nil.

package.path = package.path .. ";/path/to/test.lua"
local test = require 'test'
print(test)
==> nil

Thoughts? (Note: I also required the file in general without assigning it to a local variable and printed its values again with nil as the returned value.)


To expand on lhf's answer:

The Lua shell reads one statement at a time. It then loads the code string with the loadstring function (or more accurately, the C API equivalent), which compiles the Lua code and returns a function that executes it. Since each statement is loaded separately, and produces a different function, they don't share local variables.

Essentially, this console input:

local test = require "test"

print(test)

if test then
    bar()
end

Is translated to this:

(function() local test = require "test" end)()

(function() print(test) end)()

(function()
    if test then
        bar()
    end
end)()

(Note that this applies to files as well. Lua 'files' are actually just functions with an implicit function(...) signature. This means you can return from the top-level of a file, as well as perform any operations you can do on functions (sandboxing, etc) on files as well.)

If you're copying code from somewhere, you can surround the code in do ... end, like so:

do
    local test = require "test"
    print(test)
end

The do ... end block counts as one statement, and scopes local variables.