[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: How to change _ENV's value in a pure C function?
- From: Xavier Wang <weasley.wx@...>
- Date: Thu, 29 Dec 2011 12:59:55 +0800
在 2011年12月29日 上午11:25,While Loop <towlyhk-luageneral@yahoo.com.hk> 写道:
> Xavier Wang <weasley.wx <at> gmail.com> writes:
>> I'm wonder how to change _ENV's value, or rebuild a new _ENV locals in
>> C function. the only idea I make out is using a wrapping lua code:
>>
>> lua_newtable(L);
>> lua_pushcfunction(L, myfunc);
>> luaL_loadstring(L, "local _ENV,func = ... return func()");
>> lua_call(L, 2, 0);
>>
>> Is there any other method to change _ENV in a C function using a pure C API?
>
> I have no experience in writing C module. But I try to sum up a few points
> from the Lua 5.2 manual. If I am wrong someone please correct me.
> (1) C function no longer have environment.
> LUA_ENVIRONINDEX and lua_getfenv are removed.
>
> (2) There is no _ENV for the C function itself. There is no way to change
> _ENV variable of the caller lua function. You can only change things
> inside the associated table.
>
> (3) C function do no inherit environment (and value/vars) from Lua function.
> To access value/vars in the environment of the caller lua function,
> pass the _ENV table or other variables to the C function as augement.
>
> (4) If the C function return a new function and you want to enclose some
> values/vars in _ENV of the caller lua function to the new function.
> You have to make a copy of those values/vars and associate them with
> the new function by lua_pushcclosure or lua_setupvalue.
>
> But the description of lua_getupvalue/lua_setupvalue is not very clear.
>
> lua_getupvalue [-0, +(0|1), -]
> const char *lua_getupvalue (lua_State *L, int funcindex, int n);
> ... (Upvalues have no particular order, as they are active through the
> whole function. So, they are numbered in an arbitrary order.)
> ... For C functions, this function uses the empty string "" as a name for all upvalues.
>
> Upvalues have no name, and lua_getupvalue return them in arbitrary order !!??
> How to distinguish which value is which value ??
>
>
>
So, you mean, there is no way to write a C function like this in Lua ?
function change_env(t)
local old_env = _ENV
_ENV = t
return old_env, t
end
I have looked into Lua5.2's module's implement, it has a C function
set_env, but this function only changed the value of the first upvalue
of current function. So if we call module in a function, not in a
file, it will be confused.
local module = module
local oldenv = _ENV
local newenv = {}
local _ENV = newenv
function mymod(...)
module(...)
function abc() end
function def() end
end
_ENV = oldenv
package.preload.mymod = mymod
local m = require 'mymod'
assert(not m.abc and not m.def) -- abc and def not in m
assert(m == module) -- module function changed the first upvalue of
function mymod, that is module function itself.
assert(newenv.abc and newenv.def) -- abc and def are in newenv.