1, LoadFile---only compile, do not run.
LoadFile compiles the code into an intermediate code and returns the compiled chunk as a function without executing the code, and LoadFile does not throw an error message but returns the error code.
LoadString is similar to loadfile, except that it is not read from a file into chunk, but is read from a string.
2, dofile----compile, run.
Dofile, the first thing to do is compile with loadfile and then run the code. We can define dofile as follows:
function Dofile (filename) Local assert (loadfile(filename)) return f () End
If LoadFile fails, the assert throws an error.
It is easy to complete the simple function dofile, he reads into the file compiles and executes. However, LoadFile is more flexible. In the event of an error, LoadFile returns nil and error messages so that we can customize the error handling. Also, if we run a file multiple times, loadfile only needs to compile once, but it can run multiple times. Dofile is compiled every time.
3, Require function--load only once.
Require and dofile a bit like, but very different, require the first time the file is loaded, the code will be executed.
However, it differs from Dofile by two points:
1. Require will search for directory loading files
2. Require will determine if the file has been loaded to avoid repeatedly loading the same file. Because of these features, require is a better function for loading libraries in Lua.
The path used by require is somewhat different from the path we see in general, and the path we see is a list of directories. The path to the require is a list of patterns, each indicating a way to narimi the file name by a virtual file name (require parameter). More specifically, each pattern is a file name that contains an optional question mark. When matched, LUA will first replace the question mark with a virtual file name and see if any such file exists. If not present, continue to match with the second pattern in the same way. For example, the path is as follows:
?;?. lua;c:\windows\?;/ usr/local/lua/?/? Lua
Try to open these files when calling require "Lili":
Lililili.luac:\windows\lili/usr/local/lua/lili/lili.lua
Require concerns only semicolons (delimiters between patterns) and question marks, and other information (directory separators, file extensions) are defined in the path.
To determine the path, LUA first checks whether the global variable Lua_path is a string, or if it is the path, otherwise require checks the value of the environment variable Lua_path, if two fail require use a fixed path (typical "?;?. Lua ").
Another feature of require is to avoid repeatedly loading the same file two times. Lua retains a list of all the files that have been loaded (saved using the table). If a loaded file exists in the table require simple return, and the table retains the name of the loaded file, not the real filename. So if you use a different virtual file name to require the same file two times, the file will be loaded twice. For example require "foo" and Require "Foo.lua", The path is "?;?. Lua "will load Foo.lua two times. We can also access the list of file names through the global variable _loaded, so we can tell if the file has been loaded or not, and we can use a little trick to get require to load a file two times. For example, require "foo" after _loaded["foo" will not be nil, we can assign it to Nil,require "Foo.lua" will load the file again.
A pattern in a path can also contain a question mark instead of a fixed path, such as:
?;?. lua;/usr/Local/default.lua
In this case, require will use this fixed file when there is no match (of course, the fixed path must be placed at the end of the pattern list to make sense). Before require ran a chunk, it defined a global variable _requiredname to hold the file name of the virtual file being required. We can extend the functionality of require by using this technique. As an extreme example, we can set the path to "/usr/local/lua/newrequire.lua" so that each call to require will run Newrequire.lua, in which case you can use _ Requiredname the value to actually load the required file. (In fact, I understand this piece of wood )
Debug
Also, if you need to handle errors in Lua, you need to use the Pcall function to encapsulate your code.
Assuming you want to run a LUA code, this code can catch all exceptions and errors while it is running.
The first step: encapsulate this code in a function
function foo () ... if Then Error End ... .. Print -- potential error: ' A ' may is not a table ... End
Step Two: Call this function using Pcall
if Pcall Then -- no errors while running ' foo ' ... Else -- ' foo ' raised an error:take appropriate actions ... End
Of course, you can call Pcall in the same way as anonymous functions:
if Pcall (functionend then ... ) Else ...
Pcall in protected mode with his first parameter and runs, so all exceptions and errors can be caught. If there are no exceptions and errors, Pcall returns True and any value returned by the call, otherwise nil plus error message is returned.
The error message is not necessarily a string (the following example is a table), and any information passed to the error will be returned by Pcall:
Local Pcall (functionerror({code=121end)print--> 121
This mechanism provides all the things we need to handle exceptions and errors in Lua. We throw an exception by error and then capture him through Pcall.
Although you can use any type of value as an error message, typically we use a string to describe the error message encountered. If an internal error is encountered (such as access to a non-table value using the index table below) LUA generates an error message itself, otherwise LUA uses the parameter passed to the error function as an error message. In any case, Lua describes as clearly as possible the errors that occur.
LocalStatus, Err =Pcall(function() A ='a'+1 End)Print(ERR)--> Stdin:1: Attempt to perform arithmetic on a string valueLocalStatus, Err =Pcall(function()Error("my error")End)Print(ERR)--> Stdin:1: My error
The error message in the example gives the file name (stdin) plus the line number.
The function error can also have a second parameter that represents the run level of the error. With this parameter you cannot deny that the error is someone else's, for example, join you wrote a function to check if the error was called correctly:
function foo (str) if type " string " Then Error ("string expected") End ... End
Someone might call this function:
Foo ({x=1})
Lua will point out that the error is foo rather than error, the actual error is generated when calling error, in order to correct this problem modify the previous code to let error report errors occur at the second level (your own function is the first level) as follows:
function foo (str) if type (str) ~= " string then error ( string expected ", 2 ) ... end
When an error occurs, we often need more errors to occur, not just where the error occurred. At least one is expected to have a complete display of the tracebacks of the call stack that caused the error to occur, and when Pcall returns an error message, he has released information about the stack where the error occurred. So, if we want tracebacks we have to get it before Pcall returns. LUA provides xpcall to implement this function, Xpcall accepts two parameters: calling function and error handling function. When an error occurs. LUA calls the error handler before the stack is freed, so you can use the debug library to collect error-related information. There are two commonly used debug processing functions: Debug. Debug and Debug.traceback, the former gives the LUA hint, you can see for yourself what happened when the error occurred; the latter creates more error messages through Traceback, which is the function that the console interpreter uses to build the error message. You can call Debug.traceback at any time to get the current running Traceback information:
Print (debug.traceback())
Finally want to say, in the program, there are many Pcall (Dofile, "**.lua") code, there are many Xpcall (func) code, really convenient.
Loadfile,dofile,require used in Lua, and finally debug