Difference between require and dofile?
require
and dofile
both load and execute Lua files. The first difference is that you pass the module name to require
and an actual file path to a Lua file to dofile
.
So what search path does require
use? This is contained in the value of package.path
: on a Unix system this would look like this (note that semicolons are used to separate items):
$> lua -e "print(package.path)"
./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua
On a Windows machine:
C:\>lua -e "print(package.path)"
.\?.lua;C:\Program Files\Lua\5.1\lua\?.lua;C:\Program Files\Lua\5.1\lua\?\init.
lua;C:\Program Files\Lua\5.1\?.lua;C:\Program Files\Lua\5.1\?\init.lua;C:\Progra m Files\Lua\5.1\lua\?.luac
It's important to note that Lua itself does not know anything about directories; it will take the module name and substitute it as '?' in each pattern and see if that file exists; if so, that is then loaded.
A very instructive error message happens if you try to require a module that does not exist. This shows you explicitly how Lua is trying to find the module by matching the path entries:
$> lua -lalice lua: module 'alice' not found:
no field package.preload['alice']
no file './alice.lua'
no file '/home/sdonovan/lua/lua/alice.lua'
no file '/home/sdonovan/lua/lua/alice/init.lua'
no file './alice.so'
no file '/home/sdonovan/lua/clibs/alice.so'
no file '/home/sdonovan/lua/clibs/loadall.so'
The second difference is the require
keeps track of what modules have been loaded, so calling it again will not cause the module to be reloaded.
The third difference is that require
will also load binary modules. In a similar fashion, package.cpath
is used to find modules - they are shared libraries (or DLLs) which export an initialisation function.
$> lua -e "print(package.cpath)"
./?.so;/usr/local/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/loadall.so C:\>lua -e "print(package.cpath)"
.\?.dll;.\?51.dll;C:\Program Files\Lua\5.1\?.dll;C:\Program Files\Lua\5.1\?51.dl l;C:\Program Files\Lua\5.1\clibs\?.dll;C:\Program Files\Lua\5.1\clibs\?51.dll;C:
\Program Files\Lua\5.1\loadall.dll;C:\Program Files\Lua\5.1\clibs\loadall.dll
package.path
and package.cpath
can be modified, changing the behaviour of require
. Lua will also use the environment variables LUA_PATH
and LUA_CPATH
if they are defined, to override the default paths.
What does './?.lua' match? This matches any Lua module in the current directory, which is useful for testing.
Why is there the pattern '/usr/local/share/lua/5.1/?/init.lua'? This is allows for self-contained packages of modules. So if there was a directory 'mylib' on the Lua path, then require 'mylib'
would load 'mylib/init.lua'.
What if the module name contains dots, such as require 'socket.core
? Lua replaces the period with the appropriate directory separator ('socket/core' or 'socket\core') and performs the search using this form. So on a Unix machine, it replaces '?' in '/usr/local/lib/lua/5.1/?.so' to give '/usr/local/lib/lua/5.1/socket/core.so' which matches.