lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


But, if I load a chunk containing one or more Lua functions, how do I cause the individual functions to be "registered"?

I've found no examples of this.

The only way to "register" a chunk is to execute it.

-- load / compile the string
>f = loadstring('function foo(x) print(x) end')

-- try to execute foo, but it doesn't exist since the string has not been executed
> foo()
stdin:1: attempt to call global 'foo' (a nil value)
stack traceback:
        stdin:1: in main chunk
        [C]: ?

-- execute f and now the foo(x) function is available
> f()
> foo('hello world')
hello world



If you want to sandbox the code you can use setfenv (which is deprecated in the upcoming 5.2 release, but there are other ways to handle the same thing in 5.2).  So starting over in a fresh lua environment:

-- load / compile the string
>f = loadstring('function foo(x) print(x) end')

-- create a sandbox to execute the unsafe code and set the environment of the f chunk
> env={}
> setfenv(f,env)

-- Now execute f to make the foo(x) function available
> f()

-- Note that foo() does not exist in the current environment:
> foo('hello world')
stdin:1: attempt to call global 'foo' (a nil value)
stack traceback:
        stdin:1: in main chunk
        [C]: ?

-- However foo does exist in the env table, but we have a "problem":
> env.foo('hello world')
[string "function foo(x) print(x) end"]:1: attempt to call global 'print' (a nil value)
stack traceback:
        [string "function foo(x) print(x) end"]:1: in function 'foo'
        stdin:1: in main chunk
        [C]: ?

-- Have to also add the print function to the environment where foo() is executing and now it works:
> env.print=print
> env.foo('hello world')
hello world


So all of this works exactly the same if you are calling the corresponding functions using the C API.  Compiling a chunk only allows you to then execute the chunk, you can't call a specific function which is inside of the chunk without executing it first which will then create the functions.  The environment where the functions are created can be manually set using setfenv







If you are trying to "sandbox" the chunk you can do it using setfenv (which is going away in Lua 5.2, but that is another story).  For example, doing the same thing directly in Lua:

> env={}
> setfenv(f,env)
> f()
> foo('hello')
stdin:1: attempt to call global 'foo' (a nil value)
stack traceback:
        stdin:1: in main chunk
        [C]: ?
> env.foo('hello world')
[string "function foo(x) print(x) end"]:1: attempt to call global 'print' (a nil value)
stack traceback:
        [string "function foo(x) print(x) end"]:1: in function 'foo'
        stdin:1: in main chunk
        [C]: ?
> env.print=print
> env.foo('hello world')
hello world
>