Lua利用自定义函数打印_G内容

时间:2021-12-25 06:03:10

前言

前几天我自己定义了一个打印table的函数,并且把实现的细节都总结在了这里—— Lua 自定义打印table函数 ,自己定义的函数一定要找一个用武之地,于是我决定拿Lua的灵魂——_G表开刀,在输出的过程中还出现了一点点问题,因此总结下来和大家分享一下。

过程

首先我是知道_G有一个字段是_G,即_G._G =_G(怎么这么变态),于是我知道这样可能会导致死循环,于是在递归table之前先判断table的名字是否是_G,如果是就直接返回,就在我认为没问题的时候,灾难还是发生了。

我发现程序运行起来以后,一个CPU占用率瞬间到达100%,一开始我还没有在意,以为这个_G表太大了,于是等了一会儿,当我发现输出文件超过300M时果断懵逼了,这绝对是死循环了啊,一个表中的内容再多,也不至于多的这样离谱,于是我手动杀死了进程。

面对300M的文本文件没有什么可怕的,拿出我的法宝Sublime Text文本编辑器打开,我发现确实是死循环了,因为_G表中不仅仅有_G,还有一个package.loaded表,这个表就是环境中已经加载的内容,结果_G.package.loaded中还有_G.package.loaded就死循环了,当我把这种情况去掉以后就可以正常的输出结果了,其中的_G._G_G.package.loaded我只输出了空表,并不是实际的内容,其他都是正常内容。

结果

_G
├── string:
| ├── sub: function: 006AEB70
| ├── upper: function: 006AEBB8
| ├── len: function: 006AE290
| ├── gfind: function: 006AE170
| ├── rep: function: 006AE3F8
| ├── find: function: 006ADFC0
| ├── match: function: 006AE368
| ├── char: function: 006ADEA0
| ├── dump: function: 006ADF30
| ├── gmatch: function: 006AE170
| ├── reverse: function: 006AE440
| ├── byte: function: 006ADE10
| ├── format: function: 006AE050
| ├── gsub: function: 006AE200
| └── lower: function: 006AE2D8
├── xpcall: function: 006AA630
├── package:
| ├── preload:
| | └── { }
| ├── loadlib: function: 006AAD80
| ├── loaded:
| | └── { }
| ├── loaders:
| | ├── 1] function: 006AAEA0
| | ├── 2] function: 006AAEE8
| | ├── 4] function: 006AAF78
| | └── 3] function: 006AAF30
| ├── cpath: ".\\?.dll;H:\\Program Files (x86)\\Lua\\?.dll;H:\\Program Files (x86)\\Lua\\loadall.dll"
| ├── config: "\\\n;\n?\n!\n-"
| ├── path: ".\\?.lua;H:\\Program Files (x86)\\Lua\\lua\\?.lua;H:\\Program Files (x86)\\Lua\\lua\\?\\init.lua;H:\\Program Files (x86)\\Lua\\?.lua;H:\\Program Files (x86)\\Lua\\?\\init.lua"
| └── seeall: function: 006AAE10
├── tostring: function: 006AA480
├── print: function: 004CE518
├── dumptree: function: 004D97C8
├── os:
| ├── exit: function: 006AD9D8
| ├── setlocale: function: 006ADBD0
| ├── date: function: 006AD828
| ├── getenv: function: 006ADA68
| ├── difftime: function: 006AD8B8
| ├── remove: function: 006ADAF8
| ├── time: function: 006ADC60
| ├── clock: function: 006AD798
| ├── tmpname: function: 006ADCF0
| ├── rename: function: 006ADB40
| └── execute: function: 006AD948
├── unpack: function: 006AA5A0
├── require: function: 006AB248
├── getfenv: function: 004CE170
├── setmetatable: function: 006AA3A8
├── next: function: 004CE3F8
├── assert: function: 004CDEE8
├── tonumber: function: 006AA3F0
├── io:
| ├── lines: function: 006ACD10
| ├── write: function: 006AD028
| ├── close: function: 006ACBF0
| ├── flush: function: 006ACC38
| ├── open: function: 006ACD58
| ├── output: function: 006ACDE8
| ├── type: function: 006ACFE0
| ├── read: function: 006ACF08
| ├── stderr: file (0FE91428)
| ├── stdin: file (0FE913E8)
| ├── input: function: 006ACC80
| ├── stdout: file (0FE91408)
| ├── popen: function: 006ACE78
| └── tmpfile: function: 006ACF50
├── rawequal: function: 004CE5A8
├── collectgarbage: function: 004CDF78
├── arg:
| ├── -1] "H:/Program Files (x86)/Lua/lua_interpreter.exe"
| └── 0] "F:\\gtest.lua"
├── getmetatable: function: 004CE200
├── module: function: 006AB1B8
├── rawset: function: 004CE6C8
├── math:
| ├── log: function: 006AF428
| ├── max: function: 006AF470
| ├── acos: function: 006AED20
| ├── huge: 1.#INF
| ├── ldexp: function: 006AF308
| ├── pi: 3.1415926535898
| ├── cos: function: 006AF080
| ├── tanh: function: 006AF8A8
| ├── pow: function: 006AF590
| ├── deg: function: 006AF0C8
| ├── tan: function: 006AF938
| ├── cosh: function: 006AEFF0
| ├── sinh: function: 006AF740
| ├── random: function: 006AF620
| ├── randomseed: function: 006AF6B0
| ├── frexp: function: 006AF278
| ├── ceil: function: 006AEF60
| ├── floor: function: 006AF158
| ├── rad: function: 006AF5D8
| ├── abs: function: 006AECD8
| ├── sqrt: function: 006AF818
| ├── modf: function: 006AF500
| ├── asin: function: 006AEDB0
| ├── min: function: 006AF4B8
| ├── mod: function: 006AF1E8
| ├── fmod: function: 006AF1E8
| ├── log10: function: 006AF398
| ├── atan2: function: 006AEE40
| ├── exp: function: 006AF110
| ├── sin: function: 006AF7D0
| └── atan: function: 006AEED0
├── debug:
| ├── getupvalue: function: 004CF670
| ├── debug: function: 006AFA58
| ├── sethook: function: 004CF748
| ├── getmetatable: function: 004CF628
| ├── gethook: function: 006AFAE8
| ├── setmetatable: function: 004CF868
| ├── setlocal: function: 004CF7D8
| ├── traceback: function: 004CF940
| ├── setfenv: function: 004CF700
| ├── getinfo: function: 004CF478
| ├── setupvalue: function: 004CF8B0
| ├── getlocal: function: 004CF508
| ├── getregistry: function: 004CF598
| └── getfenv: function: 006AFAA0
├── pcall: function: 004CE488
├── table:
| ├── setn: function: 006AC4E8
| ├── insert: function: 006AC3C8
| ├── getn: function: 006AC2A8
| ├── foreachi: function: 006AC218
| ├── maxn: function: 006AC338
| ├── foreach: function: 006AC188
| ├── concat: function: 006AC0F8
| ├── sort: function: 006AC578
| └── remove: function: 006AC458
├── newproxy: function: 006A8E40
├── type: function: 006AA510
├── coroutine:
| ├── resume: function: 006AA990
| ├── yield: function: 006AABD0
| ├── status: function: 006AAAB0
| ├── wrap: function: 006AAB40
| ├── create: function: 006AA900
| └── running: function: 006AAA20
├── _G:
| └── { }
├── select: function: 004CE758
├── gcinfo: function: 004CE0E0
├── pairs: function: 006A8DE8
├── rawget: function: 004CE638
├── loadstring: function: 004CE368
├── ipairs: function: 006A18F8
├── _VERSION: "Lua 5.1"
├── dofile: function: 004CDFC0
├── setfenv: function: 004CE7E8
├── load: function: 004CE2D8
├── error: function: 004CE050
└── loadfile: function: 004CE248

总结

  • 遇到实际的问题可以先猜一下原因,然后通过代码来证明你的猜想是否正确。