Lua中的_G元表不起作用。

我正在尝试控制交互式环境。以下是我的尝试:

home: lua
Lua 5.0.3  Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> for n in pairs(_G) do io.write(n) end
stringxpcallLUA_PATHtostringgcinfoloadlibosunpackrequiregetfenvsetmetatablenext_TRACEBACKasserttonumberiorawequalcollectgarbagegetmetatable_LOADEDrawsetmathLUA_CPATHpcalldebug__powtypetablecoroutineprint_Gnewproxyrawgetloadstring_VERSIONdofilesetfenvpairsipairserrorloadfile>
> G=_G
> _G={}
> setmetatable(_G,{__index=G,__newindex=function() print("nope") end})
> for n in pairs(_G) do io.write(n) end
> x=3
>

我期望看到在输入“x = 3”命令后看到“nope”。然而,它却通过了。_G 不是空的吗?而且任何对 _G 的访问/更新都将经过定义的元方法吗?

点赞
用户3677376
用户3677376

来自 Lua 5.0 手册:

_G

一个全局变量(不是函数),保存着全局环境(即 _G._G = _G)。Lua本身不使用这个变量,改变它的值不会影响到任何环境(使用setfenv来改变环境)。

更具体地说,在交互式Lua解释器中,你需要使用setfenv(0, new_global_env)来将当前运行线程的环境更改为new_global_env

例如:

Lua 5.0.3  Copyright (C) 1994-2006 Tecgraf, PUC-Rio
> do
>> local rawget, print, _G = rawget, print, _G
>> local new_global_env = setmetatable( { tostring = tostring }, {
>>   __index = function( t, k )
>>     print( "get", k )
>>     return rawget( _G, k )
>>   end
>> } )
>> setfenv( 0, new_global_env )
>> end
> print( "hello" )
get print
hello
>

rawgetprint_G的上值,以及新的tostring全局变量,都是为了避免无限递归。)

2015-11-29 03:29:28