lua-users home
lua-l archive

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


> If you use setfenv(0, sometable) to alter the
> globals for the current
> thread, does that affect the top-level only, or also
> any function
> without an otherwise set function environment?

It is a funny business, but setfenv(0, sometable)
mostly affects C functions that rely on
LUA_GLOBALSINDEX and has almost(*) no effect on
already instantiated lua closures.  The point being
that every single existing closure just holds on to
its own environment.

To add to the confusion, the lua chunk that makes the
setfenv(0, sometable) call is a closure itself and so
not affected by this change of global environment. 
This means that any new closure created by the chunk
*still* does not get `sometable' as its globals. 
However, new chunks loaded with "loadstring" or
"loadfile" *do* inherit the new globals environment.

(*) There are places where Lua implicitly uses `top
level' globals (i.e. those at LUA_GLOBALSINDEX.) 
Examples are `tostring' and `next' that are used by
`print' and `for .. in ..' respectively.  This can
lead to some pretty confusing behaviour:

Try to predict what the following script produces:

----
x = "hi there!"
function f() print(x) end

f()
setfenv(0, {x = "what?!?"})
f()
----

The error can be fixed by adding "tostring = tostring"
to the new globals table...

Here's another one:

----
setfenv(0, {tostring = tostring})

x = "hi there!"
print(x)
loadstring "x = 123" ()
print(x)
----

Using `dofile' instead of the `loadstring' construct
has the same effect.  Can you guess what happens if
you use `require'?

--
Wim



	
		
__________________________________
Do you Yahoo!?
Yahoo! Domains ? Claim yours for only $14.70/year
http://smallbusiness.promotions.yahoo.com/offer