lua-users home
lua-l archive

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


Wim Couwenberg wrote:
 > I myself wanted to be able to alter functions to use the globals of
 > the thread in which they are invoked as opposed to having the hassles
 > of managing multiple closures for multiple lua threads.

No hassle. My previously posted example uses only a *single* closure for each thread (have a peek.) However...
Your right there, i missed that completely.

I like this idea (reminds me of the Lua 4 days too...) and would like to add another suggestion: store the environment of a closure in an UpVal and pass the UpVal pointer around instead of the raw Table pointer. (This was suggested to me a *long* time ago by Rici. Where is he by the way?) This has the advantage that a setfenv changes the environment of all "related" closures at once, e.g. all closures defined in a single script/module. This makes the "single level" setfenv problem mentioned by Willieam Ahern go away in many (all?) relevant cases.
Perhaps i have missed something. From my examinations of the code all 
closures inherit the environment in which they are created, changing 
this to a reference would enable all "related" closures to be changed 
which makes sense. Whether one would want this i am not sure, if one has 
a closure (child) created inside another closure (parent) and one wants 
to change the child closure then presumably the parent closure would be 
altered as well as they would both reference the same environment which 
is being changed? If the child closure environment gets replaced without 
affecting the parent closure (ie a new private environment) then what 
would happen to the children of the child closure being changed, should 
they be given the new private environment?
The ability to change the environment of a single closure to be its own 
or "dynamically" bound has several solutions. I think the problems lies 
in how does one change the environment of closures that have inherited 
its value from a given closure without affecting the parent closures?
The only way that i can think of being able to change closures from a 
given point in a closure "tree" and have all child closures changed 
would be to maintain a tree of the closures, ie a closure would then 
contain a list of closures that have inheritted from it, that way a 
setfenv you could say how far down the tree you want to replace etc. 
Alternatively the environment could be stored as a reference, this would 
reference an inherited environment, or a table. This solution would 
require traversing a list of parent "environments" until a table is 
found if the current environment is not a table to determine what is the 
given environment for the closure.
I think the maintaining a closure hierachy would be the simpler form to 
implement than the parent inheritance. Effectively it could be 
implemented as a weak key'd table where the key is the coroutine, the 
value is a weak valued table which contains the list of child closures 
created. The key would be something unique and the value would be the 
closure.
By all means if i have provided false or incorrect information above 
please correct me.
Andrew