Eval - Running code within code


dofile ([filename]) Opens the named file and executes its contents as a Lua chunk. When called without arguments, dofile executes the contents of the standard input (stdin). Returns all values returned by the chunk. In case of errors, dofile propagates the error to its caller (that is, dofile does not run in protected mode).

load (func [, chunkname]) Loads a chunk using function func to get its pieces. Each call to func must return a string that concatenates with previous results. A return of an empty string, nil, or no value signals the end of the chunk.
If there are no errors, returns the compiled chunk as a function; otherwise, returns nil plus the error message. The environment of the returned function is the global environment.
chunkname is used as the chunk name for error messages and debug information. When absent, it defaults to "=(load)".

loadfile ([filename]) Similar to load, but gets the chunk from file filename or from the standard input, if no file name is given.

loadstring (string [, chunkname]) Similar to load, but gets the chunk from the given string.
To load and run a given string, use the idiom assert(loadstring(s))() When absent, chunkname defaults to the given string.

Let's look at a few examples

We'll just try a few things out and see how they'll run. Remember to click on the green button to see what acctually happens with the code.


Executing code from a file

There's two ways of doing this, we can either directly use dofile, which loads the file and executes it directly, as below


Alternatively, you can compile the file into a function. You can then call it yourself to execute it.

                    local file = assert(loadfile("file.lua"))

Executing code from a string

Just use loadstring

                    code = [[
                        print("Hello World")
                    hi = loadstring(code)

Passing in lua objects to loaded code

Suppose the code you're loading requires some objects to execute, but you don't know how to turn that object into a string. Well, since all code share the same gloabl space, we can have both reference some table called "shared_objects"

                    shared_objects = {"Hello World"}
                    code = [[
                    echo = loadstring(code)

Loading bytecode

Loadstring can be used to load bytecode produced from string.dump. A popular use of producing bytecode instead of giving the full file is so that it is more difficult to recover the source file, and hence serve as a simple form of obfuscation.

                    x = "Hello World"
                    code = string.dump(function() print(x) end)
                    hi = loadstring(code)

Closing Remarks

There are quite a few creative uses of eval-type functions. However, due to the fact that the more creative and powerful they are, the more likely that they'll potentially end up biting you in the ass, it is generally not advisable to use them too often. However, that doesn't mean you should shy away from them. There's a difference between being wary of something because of past experiences and being stuborn in your own ignorance. The generally accepted alternative is the require function.

blog comments powered by Disqus

The.Lua.Tutorialby Lee Gao.