3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

LuaAdvent Calendar 2022

Day 22

luaでテーブルの中身を曝け出す

Posted at

 
この記事はアドカレに参加しています。

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のテーブルをコンソールに書き出す]]
?>

おわりに

テーブルの中身を曝け出しました。
人肌に触れてテーブルも喜んでいますね!(え?

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?