1. Compile:
Lua providesDofileFunction, which is a built-in operation used to run LuaCodeBlock. But in fact, dofile is just an auxiliary function,LoadFileIs the true core function. Compared with dofile, LoadFile only loads the Lua code block from the specified file and then compiles the code block. If any compilation error occurs, Nil is returned and an error message is provided, however, this code block is not actually executed after compilation. Therefore, we can implement dofile as follows:
1 Function Dofile(Filename)
2LocalF =Assert(LoadFile(Filename ))
3ReturnF ()
4 End
If LoadFile fails to be executed, the assert function directly triggers an error. Through the dofile code, we can also see that if we want to run the Lua code block in a file multiple times, we can only execute LoadFile once and then run the returned results multiple times, in this way, the overhead caused by multiple compilation can be saved. This is also the performance difference between LoadFile and dofile.
Lua also provides another method for dynamically executing Lua code, that is, loadstring function. As the name suggests, compared with LoadFile, loadstring code source comes from strings in its parameters, such as:
F = loadstring (" I = I + 1 ")
F becomes a function, execute "I = I + 1" for each call, for example:
1I =0
2F ()
3 Print(I)--Output 1
4F ()
5 Print(I)--2
Loadstring is indeed a powerful function, but the performance overhead we have to consider. Therefore, if many constant strings still use the loadstring method, it does not make much sense. In the above example, F = loadstring ("I = I + 1 "), because we can replace it with F = function () I = I + 1 end. The execution efficiency of the latter is much higher than that of the former. After all, the latter is compiled only once, while the former is compiled every time loadstring is called. For loadstring, we also need to note that this function always compiles its string in the global environment, so it will not be able to file local variables, but can only access global variables, such:
1 I =32
2 Local I = 0
3 F = Loadstring ( " I = I + 1; print (I) " )
4 G = Function () I = I + 1 ; Print (I) End
5 F () -- The I in the f function is the global variable I, so 33 is output.
6 G () -- The I in the G function is the local variable I, so the output 1
For functions returned by loadstring, if you need to evaluate an expression, you must add return before it to form a statement and return the value of the expression, for example:
1I =32
2F =Loadstring("I = I + 1; return I * 2")
3 Print(F ())--Output 66
4 Print(F ())--Output 68. Because loadstring returns a regular function, it can be called repeatedly.
LuaProgramBlock is regarded as the function body of an anonymous function, and the anonymous function also has a variable length real parameter. Therefore, when loadstring is called, you can pass parameters for it, for example:
1 Local I = 30
2 -- The following... indicates a variable-length real parameter. The value is assigned to the local variable X.
3 Local F = Assert ( Loadstring ( " Local x =...; Return (x + 10) * 2 " ))
4 For I =1 , 20 Do
5 Print ( String. Rep ( " * " , F (I )))
6 End
2. C code:
The previous section describes how to dynamically load Lua code. In fact, Lua itself supports dynamically loading the code in the C dynamic library. To complete this operation, we need to use the built-in system functions of Lua.Package. loadlib. The function has two string parameters: the full file name of the dynamic library and the function name contained in the library. The typical Call Code is as follows:
Local Path = "/usr/local/lib/test. So"
Local F = package. loadlib (path, "test_func ")
Because loadlib is a very underlying function, the complete path name and function name must be provided during the call.
3. Error:
As an embedded scripting language, Lua should not simply quit or crash when an error occurs. On the contrary, once an error occurs, Lua should end the current program block and return it to the application.
In Lua, we can use the error () function to obtain the error message, for example:
Print "enter a number :"
N = Io. Read ("* Number ")
If not n then error ("invalid input") End
The last line in the above Code can be assisted by another built-in function assert provided by Lua, such:
Print "enter a number :"
N = assert (Io. Read ("* Number"), "invalid input ")
The assert function checks whether the first parameter is true. If yes, this parameter is simply returned. Otherwise, an error is thrown. The second parameter is an optional string.
For all Programming Language Error handling is a very important step. In actual development, there is no unified guiding principles. It is only possible to combine the current application scenarios after careful analysis in the case of problems, finally, the specific error handling method is provided based on your own experience. In some cases, we can directly return error codes. In other cases, we need to directly throw an error so that developers can quickly locate the source code that causes the error.
4. Error Handling and exceptions:
Lua provides the error handling function pcall. The first parameter of this function is the function that requires "Protection of execution". If the function fails to be executed, pcall returns false and error information, otherwise, the return values of true and function call are returned. See the following code:
1 Function Foo ()
2 Local A = 10
3 Print ([ 2 ])
4 End
5
6 R, MSG = Pcall (FOO)
7 If R Then
8 Print ( " This is OK. " )
9 Else
10 Print (" This is error. " )
11 Print (MSG)
12 End
13 -- Output result:
14 -- This is error.
15 -- D:/test. Lua: 3: Attempt to index local 'A' (a number value)
We can also directly pass anonymous functions to pcall functions, such:
1 R, MSG = Pcall ( Function () Error ({Code = 121 }) End )
2 If R Then
3 Print ( " This is OK. " )
4 Else
5 Print ( " This is error. " )
6 Print (Msg. Code)
7 End
8 -- Output result:
9 -- This is error.
10 -- 121
5. error message and tracing:
Generally, when an error occurs, you want more debugging information, instead of the location where the error occurs. Trace at least to the time when an error occurs and the status of the function call, and display a complete function call stack trajectory. To complete this function, we need to use another built-in function provided by Lua.Xpcall. In addition to a function to be called, this function also accepts the second parameter, namely the error processing function. When an error occurs, Lua calls the error processing function before calling the stack expansion. In this way, we can use the debug library in this functionDebug. tracebackFunction, which constructs an extended error message based on the call stack. For example:
1 Function Errorfunc ()
2 Local A = 20
3 Print ([ 10 ])
4 End
5
6 Function Errorhandle ()
7 Print ( Debug. traceback ())
8 End
9
10 If Xpcall (Errorfunc, errorhandle) Then
11 Print ( " This is OK. " )
12 Else
13 Print ( " This is error. " )
14 End
15
16 -- Output result:
17 --[[ Stack traceback:
18 D:/test. Lua: 7: In function <D:/test. Lua: 6>
19 D:/test. Lua: 3: In function <D:/test. Lua: 1>
20 [C]: In function 'xpcall'
21 D:/test. Lua: 10: in main chunk
22 [C]:?
23 This is error.
24 -- ]