compile
- lua is an interpreted language
- But lua allows source code to be compiled into an intermediate form before running it
- The main characteristic that distinguishes interpreted languages is not whether they can be compiled
- Whether the compiler is part of the language runtime library
- Is it capable of executing dynamically generated code
loadfile function
-
The dofile function is a built-in operation for running blocks of lua code
-
dofile just does the auxiliary work of loadfile
-
loadfile will load lua code blocks from a file
-
but will not run the code, just compile the code
-
Then return the compiled result as a function
-
dofile throws an error
-
loadfile just throws error values, but doesn't handle errors
function dofile(filename) -- assert return error value local f = assert(loadfile(filename)) return f() end
- When an error occurs, loadfile will return nil and an error message, which can be customized
- When you need to run a file multiple times, you only need to call loadfile once, and call its return result multiple times, that is, the function.
- The overhead of dofile is much larger than that of loadfile, because loadfile only compiles the file once
loadstring function
- read code from a string
- also returns a function
- Inexpensive because it compiles once every time loadstring is called
- And the way of writing function is only compiled once when compiling for the program block
i = 0 f = loadstring("i = i + 1") -- equal to f = function() i = i + 1 end f() print(i) -- 1 f() print(i) -- 2 -- dostring Finish loading and running the code assert(loadstring(s))() -- Grammatical errors "attempt to call a nil value"
- loadstring compiles without lexical domains
- loading only compiles strings in the global environment, not the local environment
i = 32 local i = 0 f = loadstring("i = i + 1; print(i)") g = function() i = i + 1; print(i) end f() -- 33 using global variables g() -- 1 using local variables
- Can execute external code
do print("enter you expression:") local l = io.read() local func = assert(loadstring("return '" .. l .. "'")) print("the value of your expression is " .. func()) end do print("enter function to be plotted(with variable 'x'):") local l = io.read() local f = assert(loadstring("return " .. l)) for i = 1, 20 do x = i print(x .. ":" .. string.rep("*", f())) end end
-
loadfile and loadstring , there is a real primitive function load
-
loadfile and loadstring read blocks from file and string respectively
-
load takes a "reader function" and calls it internally to get the block
-
The reader function can return a block several times, and load will call it repeatedly until it returns nil (indicating the end of the block)
-
load is only used when the block is not in the file, or if the block is too large to fit in memory
-
lua treats all independent program blocks as the body of an anonymous function that also has variable-length arguments
-
Like other functions, local variables can be declared in a block
loadstring("a = 1") -- equal to function(...) a = 1 end f = loadstring("local a = 10; print(a + 10)") f() -- 20
- Rewrite the read input example to avoid using the global variable x
print("enter function to be plotted (with variable 'x'):") local l = io.read() local f = assert(loadstring("local x = ...; return " .. l)) for i = 1, 20 do print(string.rep("*", f(i))) end
- The load function does not throw an error. When an error occurs, load will return nil with an error message
print(loadstring("a a")) -- nil [string "a a":1 '=' expected nead 'a']
- loadfile and loadstring have no side effects
- They just compile the block into an intermediate representation and return the result as an anonymous function.
- instead of loading a block, or defining a function within it
- A function definition is an assignment operation that is done at runtime.
-- write a lua file, named foo function foo(x) print(x) end -- exist cmd middle lua input in the interpreter f = loadfile("you store foo file path") print(foo()) -- nil f() -- define function foo("test") -- test
- Execute some operation of external code
- Report any errors when processing loader blocks
- If the code is not trusted, it needs to be executed in a protected environment (i.e. the aforementioned "sandbox")