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