2

I had some lua code with the following line:

JSON = loadfile("JSON.lua")()

The file JSON.lua is in the same directory as the lua code that line came from. This code worked for me for a while, and then, without my changing either the lua source, or the JSON.lua, or permission of any of the files, or the directory from where I was running the lua code, I started getting a nil error on that line. (I simply recall NO relevant changes that could have any impact on the lua code.)

Adding an assert revealed that the error was caused by the file not being found. Playing with file permissions, restarting my machine didn't resolve the issue, and pulling back code that I had checked in and was working perfectly did not resolve the error.

I resolved the error by changing the line above to provide the absolute path to that JSON.lua file.

Is there anything explaining why the code without the absolute path could have worked for a while and then stopped working?

Note: This behavior of working and then not working happened to me twice over a week. I am puzzled and though I have now found a fix, I am really curious as to the explanation for that intermittent behavior.

tshepang
  • 12,111
  • 21
  • 91
  • 136
Lolo
  • 3,935
  • 5
  • 40
  • 50
  • 1
    Using loadfile the way you use it can be dangerous. At least wrap it in assert, and try to use require function for loading libraries and other files. – Bartek Banachewicz Dec 25 '12 at 08:54
  • Ok. Is local f = assert(loadfile(filename)) followed by f() enough or are you suggesting I do even more? Also, the existence of that package.path mentioned by Doug makes me wonder: is it a better practice to specify the absolute path, or is it better to make it relative and set package.path correctly using luaconf.h? – Lolo Dec 26 '12 at 04:14
  • 1
    It's usually better to use relative paths and path variables (regardless of language and IDE), because it leads to a more flexible project setup. Whenever simple assert is enough depends on the size of your project. If it's mission critical, I would of course add more protection, but for simple script it should be fine. – Bartek Banachewicz Dec 26 '12 at 14:42

2 Answers2

2

Lua uses package.path, whose default value comes from the environment variable LUA_PATH if it is set, as the list of directories to search. You can put . of the front of this list to load files from the current directory, or you can put your files in a path on the list.

Doug Currie
  • 40,708
  • 1
  • 95
  • 119
  • Thank you. At least now I have some kind of explanation as to what could have caused the code to work intermittently: *something* must have affected the value of that package.path. I am not going to dig deeper and I will just remember for the future to set the full path for the files I load, or have a luaconf.h setting the correct paths I need to be included. – Lolo Dec 26 '12 at 04:11
  • You're sure this is right for loadfile? I thought only `require` uses the `package.path` variable...?? – Roddy Oct 18 '15 at 19:37
  • @Roddy, I believe you are correct, only `require` uses `package.path`. – Doug Currie Oct 19 '15 at 14:20
2

A late answer on this, as I found exactly the same problem.

First, contrary to the previous answer, loadfile doesn't use the package.path search path. It only looks in the specified directory. And if you don't specify a directory, it only look in the 'current directory'. I can't explain exactly why it stopped working for you, but probably your Lua code is somehow being run with a different 'current directory' than previous.

There are two possible fixes: One is to specify an absolute path to loadfile.

JSON = loadfile("c:\\my_folder\\JSON.lua")()

The alternative fix depends on the particular library you're using, which I suspect is Jeffrey Friedl's Lua JSON lilbrary. Because this supports the newer Lua module mechanism, you can just load the module with require, which does support the package.path search path.

JSON = require("JSON")
Roddy
  • 66,617
  • 42
  • 165
  • 277