Search code examples
windowsluapathatom-editorrequire

Unable to load/require file from Lua running from Atom in Windows


I'm trying to use Atom to run a Lua script. However, when I try to load files via the require() command, it always says it's unable to locate them. The files are all in the same folder. For example, to load utils.lua I have tried

require 'utils'
require 'utils.lua'
require 'D:\Users\Mike\Dropbox\Lua Modeling\utils.lua'
require 'D:\\Users\\Mike\\Dropbox\\Lua Modeling\\utils.lua'
require 'D:/Users/Mike/Dropbox/Lua Modeling/utils.lua'

I get errors like

Lua: D:\Users\Mike\Dropbox\Lua Modeling\main.lua:12: module 'D:\Users\Mike\Dropbox\Lua Modeling\utils.lua' not found:
    no field package.preload['D:\Users\Mike\Dropbox\Lua Modeling\utils.lua']
    no file '.\D:\Users\Mike\Dropbox\Lua Modeling\utils\lua.lua'
    no file 'D:\Program Files (x86)\Lua\5.1\lua\D:\Users\Mike\Dropbox\Lua Modeling\utils\lua.lua'
    no file 'D:\Program Files (x86)\Lua\5.1\lua\D:\Users\Mike\Dropbox\Lua Modeling\utils\lua\init.lua'
    no file 'D:\Program Files (x86)\Lua\5.1\D:\Users\Mike\Dropbox\Lua Modeling\utils\lua.lua'

The messages says on the first line that 'D:\Users\Mike\Dropbox\Lua Modeling\utils.lua' was not found, even though that is the full path of the file. What am I doing wrong?

Thanks.


Solution

  • The short answer

    You should be able to load utils.lua by using the following code:

    require("utils")
    

    And by starting your program from the directory that utils.lua is in:

    cd "D:\Users\Mike\Dropbox\Lua Modeling"
    lua main.lua
    

    The long answer

    To understand what is going wrong here, it is helpful to know a little bit about how require works. The first thing that require does is to search for the module in the module path. From Programming in Lua chapter 8.1:

    The path used by require is a little different from typical paths. Most programs use paths as a list of directories wherein to search for a given file. However, ANSI C (the abstract platform where Lua runs) does not have the concept of directories. Therefore, the path used by require is a list of patterns, each of them specifying an alternative way to transform a virtual file name (the argument to require) into a real file name. More specifically, each component in the path is a file name containing optional interrogation marks. For each component, require replaces each ? by the virtual file name and checks whether there is a file with that name; if not, it goes to the next component. The components in a path are separated by semicolons (a character seldom used for file names in most operating systems). For instance, if the path is

    ?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua
    

    then the call require"lili" will try to open the following files:

    lili
    lili.lua
    c:\windows\lili
    /usr/local/lua/lili/lili.lua
    

    Judging from your error message, your Lua path seems to be the following:

    .\?.lua;D:\Program Files (x86)\Lua\5.1\lua\?.lua;D:\Program Files (x86)\Lua\5.1\lua\?\init.lua;D:\Program Files (x86)\Lua\5.1\?.lua
    

    To make that easier to read, here are each the patterns separated by line breaks:

    .\?.lua
    D:\Program Files (x86)\Lua\5.1\lua\?.lua
    D:\Program Files (x86)\Lua\5.1\lua\?\init.lua
    D:\Program Files (x86)\Lua\5.1\?.lua
    

    From this list you can see that when calling require

    1. Lua fills in the .lua extension for you
    2. Lua fills in the rest of the file path for you

    In other words, you should just specify the module name, like this:

    require("utils") 
    

    Now, Lua also needs to know where the utils.lua file is. The easiest way is to run your program from the D:\Users\Mike\Dropbox\Lua Modeling folder. This means that when you run require("utils"), Lua will expand the first pattern .\?.lua into .\utils.lua, and when it checks that path it will find the utils.lua file in the current directory.

    In other words, running your program like this should work:

    cd "D:\Users\Mike\Dropbox\Lua Modeling"
    lua main.lua
    

    An alternative

    If you can't (or don't want to) change your working directory to run the program, you can use the LUA_PATH environment variable to add new patterns to the path that require uses to search for modules.

    set LUA_PATH=D:\Users\Mike\Dropbox\Lua Modeling\?.lua;%LUA_PATH%;
    lua "D:\Users\Mike\Dropbox\Lua Modeling\main.lua"
    

    There is a slight trick to this. If the LUA_PATH environment variable already exists, then this will add your project's folder to the start of it. If LUA_PATH doesn't exist, this will add ;; to the end, which Lua fills in with the default path.