この記事はアドカレに参加しています。
luaでテーブルの中身を曝け出す
luaにはテーブルという便利な機能があります。
なにが便利かというと、キーに数字と文字を扱うことができたりするところです。
local a={}
a[1]=0
a[10]=0
a["key"]=100
a["test"..10]="aiueo"
とても便利ですね。
さて、ここで気を付けておきたいのが変数名被りです。
local a={}
a["name"]="Tom"
--[[なんらかの処理~~~~]]
a["name"]="Emma"
うっかりこんなことをやってしまった日には、トムが男の娘になってしまいます。それもいいですね
これを防ぐためには、正確にテーブルの中身を知る必要があります。
そこで、テーブルの中身をprintするプログラムを書きました。
コード
少し駄目なところがありますが、このプログラムを考えていたときは頭がいっぱいいっぱいだったのでご容赦を。
<?
--[[渡されたテーブルの中身をdebug_printする関数]]
local function load_G(m,mt,s)
if(type(mt)~="table")then
mt={m}
else
mt[#mt+1]=m
end
--これ、どうにかしたいね…
--debug_print(string.format("%d",#mt))
for k,v in pairs(m) do
debug_print(s..k.." = "..tostring(v).."\n")
if(type(m[k])=="table")then
local ch=1
for i=1,#mt do
if(mt[i]==m[k])then
ch=0
break
end
end
if(ch==1)then
load_G(m[k],mt,s..k..".")
end
end
end
end
TEST={}
local c=0
for i=1,10 do
TEST[i]={}
for j=1,10 do
c=c+1
TEST[i][j]=c
end
end
os.execute("cls")--[[コンソールクリア]]
load_G(_G,0,"_G.")--[[_Gのテーブルをコンソールに書き出す]]
?>
理論
まず、テーブルのすべての要素にアクセスするには汎用for文を使います。
これとかシンプルで分かり易いです。
以下のコードはただ書き直しただけです。
<?
debug_print("グローバル変数の表示")
for n in pairs(_G) do
debug_print(n)
end
?>
次に、テーブルの要素がテーブルだったときのことを考えます。
もし要素がテーブルだったら、そのテーブルの中身を曝け出せばいいことになります。再帰処理でできますね。
<?
--[[渡されたテーブルの中身をdebug_printする関数]]
local function load_G(m,s)
for k,v in pairs(m) do
debug_print(s..k.." = "..tostring(v).."\n")
if(type(m[k])=="table")then
load_G(m[k],s..k..".")
end
end
end
--[[ちゃんと表示されるか確認するための配列]]
TEST={}
for i=1,1000 do
TEST[i]=i
end
os.execute("cls")--[[コンソールクリア]]
load_G(_G,"_G.")--[[_Gのテーブルをコンソールに書き出す]]
?>
はい、ここで例外を考えなければなりません。
_Gです。
_Gは、それ自身に_Gという要素を持っています。
つまり、
_G._G._G._G._G._G._G・・・・・
無限ループです。
なので、これを防ぐ必要があります。
方法としては、一度表示したものを記録しておいて、もし次に表示しようとしているものが既に表示したものならば、表示しないようにすればいいです。
<?
--[[渡されたテーブルの中身をdebug_printする関数]]
local function load_G(m,mt,s)
if(type(mt)~="table")then
mt={m}
else
mt[#mt+1]=m
end
--これ、どうにかしたいね…
--debug_print(string.format("%d",#mt))
for k,v in pairs(m) do
debug_print(s..k.." = "..tostring(v).."\n")
if(type(m[k])=="table")then
local ch=1
for i=1,#mt do
if(mt[i]==m[k])then
ch=0
break
end
end
if(ch==1)then
load_G(m[k],mt,s..k..".")
end
end
end
end
TEST={}
local c=0
for i=1,10 do
TEST[i]={}
for j=1,10 do
c=c+1
TEST[i][j]=c
end
end
os.execute("cls")--[[コンソールクリア]]
load_G(_G,0,"_G.")--[[_Gのテーブルをコンソールに書き出す]]
?>
おわりに
テーブルの中身を曝け出しました。
人肌に触れてテーブルも喜んでいますね!(え?