开发者

trying to print _G doesn't work

According to the documentation _G开发者_C百科 "holds the global environment". I wanted to see what's inside it so I wrote the following code to print _G but it doesn't work:

function f(x)
    return 2*x
end
a=3
b="hello world"
print("_G has "..#_G.." elements")
for k,v in pairs(_G) do
    print(k)
    print(_G[k])
    print("G["..k.."]=".._G[k])
end

Error:

_G has 0 elements
a
3
G[a]=3
string
table: 003C8448
lua: try_G.lua:10: attempt to concatenate field '?' (a table value)
stack traceback:
    try_G.lua:10: in main chunk
    [C]: ?
>Exit code: 1


You could also use the table.foreach(t,f) function. It iterates over a table t, calling the function f with each key and value pair. Use with print to get a quick view:

table.foreach(_G,print)

This is really handy at the interactive prompt as it is reasonably succinct and easy enough to type.

C:\Users\Ross>lua
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> table.foreach(_G,print)
string  table: 005CE3D0
xpcall  function: 00717E80
package table: 005CE088
tostring        function: 00717DE0
print   function: 00711CB8
os      table: 005CE358
unpack  function: 00717E40
require function: 00718360
getfenv function: 00711B58
setmetatable    function: 00717DA0
next    function: 00711C38
assert  function: 00711A38
tonumber        function: 00717DC0
io      table: 005CE218
rawequal        function: 00711CF8
collectgarbage  function: 00711A78
getmetatable    function: 00711B98
module  function: 00718320
rawset  function: 00711D58
math    table: 005CE448
debug   table: 005CE498
pcall   function: 00711C78
table   table: 005CE128
newproxy        function: 00711E10
type    function: 00717E00
coroutine       table: 005CDFE8
_G      table: 00713EC8
select  function: 00711D98
gcinfo  function: 00711B18
pairs   function: 00711F98
rawget  function: 00711D18
loadstring      function: 00711C18
ipairs  function: 00711F68
_VERSION        Lua 5.1
dofile  function: 00711A98
setfenv function: 00717D60
load    function: 00711BD8
error   function: 00711AD8
loadfile        function: 00711BB8
>

Update: Unfortunately, as Alexander Gladysh reminds me, the table.foreach function was deprecated in Lua 5.1, and a quick check of the current beta release of 5.2 shows that it has been removed in Lua 5.2. It is easy to write the same loop in terms of pairs:

for k,v in pairs(_G) do print(k,v) end

which should give the same output as table.foreach(_G,print) would. The key feature that I'm leaning on here is that print is defined to call tostring() on each argument you pass, and tostring() is defined to return some sort of sensible string for every kind of value, even those like functions that don't have a good representation as a string. The details will differ on each platform, but the default implementation of tostring() includes the address of the table or function in its string result, allowing you to at least recognize that _G.os and _G.io are distinct tables.

For more human-friendly table printing, there are a lot of solutions, ranging from examples in PiL to several persistent data libraries. Personally, I like the pl.pretty.write() function provided by steve donavan's penlight library.


Your code works exactly as expected- it loops through _G and attempts to print the contents. Unfortunately, _G contains many tables which cannot be concatenated into a string. The code fails because _G["_G"] = _G. That means that when the interpreter comes to

print("G["..k.."]=".._G[k])

then k is "_G" and _G[k] is _G, and you attempt to concatenate a table- which the interpreter can't do, so it dies on you. There are numerous other tables in _G which would also cause this failure.


To follow up on DeadMG, change your

print("G["..k.."]=".._G[k])

to

print("G["..k.."]=",_G[k])

and you should be fine.


Here is the final code using DeadMG's solution:

function f(x)
    return 2*x
end
a=3
b="hello world"
print("_G has "..#_G.." elements")
for k,v in pairs(_G) do
    if k~="_G" then
        if type(v)=="string" or type(v)=="number" then
            print("G["..k.."]="..v)
        else
            print("G["..k.."]=("..type(v)..")")
        end
    end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜