4
4

More than 5 years have passed since last update.

tableの値をdumpする+α

Posted at

facebookでリクエストがあったので晒しておきます。
tableの値をdump出力したり、それを実機でコピペ可能状態なテキストフィールドにトレースしたりするクラスです。
ソースが長いのでココにzipで固めておきます。

log.lua

module(..., package.seeall)

local DEBUG = 1;
local INFO  = 2;
local WARN  = 4;
local ERROR = 8;
local RELEASE = 16;

--しきい値設定
local logLevel = DEBUG;     

--デバッグディスプレイのボタンサイズ
local buttonsize = 30;


--Debug Display------------------------------------------------------------------------

--実機検証用

local displayObject = display.newGroup();
local disp;
local dispButton;
local delButton;
local displayEnable = false;


local function visibleDisplay( event )
    disp.isVisible = not( disp.isVisible );
end;

local function deleteDisplay( event )
    disp.text = "";
end;


-- 実機検証用のディスプレイを表示
-- colorObj     { r ,g ,b ,a }  ディスプレイの文字色設定(各0〜255)、設定があれば背景は透明/nil時は背景白、文字黒

function showDisplay( colorObj )
    print( "showDisplay!!!!!" );
    displayEnable = true;

    dispButton = display.newRect(display.screenOriginX,display.screenOriginY,buttonsize,buttonsize);
    dispButton.strokeWidth = 3;
    dispButton:setFillColor(255, 0, 0);
    dispButton:addEventListener( "tap" , visibleDisplay );

    delButton = display.newRect(display.screenOriginX,display.screenOriginY+buttonsize+10,buttonsize,buttonsize);
    delButton.strokeWidth = 3;
    delButton:setFillColor(0, 0, 255);
    delButton:addEventListener( "tap" , deleteDisplay );

    disp = native.newTextBox( buttonsize, 0, display.contentWidth-buttonsize, display.contentHeight );
    disp.font = native.newFont( native.systemFont , 12 );
    disp.isVisible = false;
    if colorObj and #colorObj==4 then
        disp:setTextColor( colorObj[1], colorObj[2], colorObj[3], colorObj[4] );
        disp.hasBackground = false;
    end;

    displayObject:insert( dispButton );
    displayObject:insert( delButton );
    displayObject:insert( disp );
end;



-- データのダンプ、ダンプした文字列を返す------------------------------------------------------------------------
-- (UserDataと循環参照を持つオブジェクトは入れてはいけません)
-- data             ダンプするデータ
-- return           ダンプした文字列
local function dump_data( data )

    if type( data ) ~= "table" then
        return tostring(data);
    end;

    dump_table = function( t, indent )
        local str = "{\n";
        for k, v in pairs( t ) do
            if type( v ) == "table" then
                str = string.format("%s%s%s%s = %s,\n", str, indent, "\t", tostring( k ),dump_table( v, indent .. "\t" ) );
            elseif type( v ) == "string" then
                str = string.format("%s%s%s%s = %q,\n", str, indent, "\t", tostring( k ), v );
            else
                str = string.format("%s%s%s%s = %s,\n", str, indent, "\t", tostring( k ), tostring( v ) );
            end;
        end;
        str = str .. indent .. "}";
        return str;
    end;

    return dump_table( data, "" );
end



-- NEW------------------------------------------------------------------------
-- _path            接頭でprintされる文字列、クラスパスを入れておくと便利

function new( _path )
    local this = {};

    if logLevel == RELEASE then
        this = {
                debug = function( value ) end;
                info  = function( value ) end;
                warn  = function( value ) end;
                error = function( value ) end;
                showDisplay = function( value ) end;
                log_display = display.newGroup();
        };      
    else
        this = {
            path = _path;
            debug = function( value )
                if  logLevel <= DEBUG then
                    local debug_text = ( "[debug][".. _path .."] " .. dump_data( value ) );
                    if displayEnable then disp.text = disp.text .. "\n" .. debug_text; end;
                    print( debug_text );
                end
            end;
            info = function( value )
                if  logLevel <= INFO then
                    local debug_text = ( "\t[info][".. _path .."] " .. dump_data( value ) );
                    if displayEnable then disp.text = disp.text .. "\n" .. debug_text; end;
                    print( debug_text );
                end
            end;
            warn = function( value )
                if  logLevel <= WARN then
                    local debug_text = ( "\t\t[warn][".. _path .."] " .. dump_data( value ) );
                    if displayEnable then disp.text = disp.text .. "\n" .. debug_text; end;
                    print( debug_text );
                end
            end;
            error = function( value )
                if  logLevel <= ERROR then
                    local debug_text = ( "\t\t\t[error][".. _path .."] " .. dump_data( value ) );
                    if displayEnable then disp.text = disp.text .. "\n" .. debug_text; end;
                    print( debug_text );
                end
            end;
            showDisplay = function( colorObj ) showDisplay( colorObj ); end;
            log_display = displayObject;
        };
    end;

    return this;
end;



-- 初回トレース ------------------------------------------------------------------------

local startLog = new( "log" );
startLog.error  ("\n\n\n\n\n\n\n\n------------------------------ DEBUG START at " .. os.date( "%c" ) .." ------------------------------\n\n");
startLog.debug  ( "this is debug." );
startLog.info   ( "this is info." );
startLog.warn   ( "this is warn." );
startLog.error  ( "this is error.\n\n" );

使用サンプル

で、以下が使用サンプルです。

main.lua
local log = ( require "log" ).new( "main" );

--実機検証用にディスプレイを表示する場合に一回だけ実行
log.showDisplay();
--displayList最前面とかにする場合は以下な感じで
--container:insert( log.log_display );

--トレースサンプル
local dump_reference = { hoge="hoge" };
local obj = {
    dump_string = "STRING";
    dump_number = 65536;
    dump_boolean = true;
    dump_array = { 50 , 80+2.56 , "THREE" , false , dump_reference };
    dump_function = function() end;
    dump_nan = 0/0;
    --dump_ng = display.newGroup(); --これは駄目よ
};

log.debug( obj.dump_string );
log.info ( obj.dump_number );
log.warn ( obj.dump_boolean );
log.error( obj.dump_array );
log.debug( obj );

出力結果はこんな感じ。

[debug][main] STRING
    [info][main] 65536
        [warn][main] true
            [error][main] {
  1 = 50,
  2 = 82.56,
  3 = "THREE",
  4 = false,
  5 = {
    hoge = "hoge",
  },
}
[debug][main] {
  dump_string = "STRING",
  dump_array = {
    1 = 50,
    2 = 82.56,
    3 = "THREE",
    4 = false,
    5 = {
      hoge = "hoge",
    },
  },
  dump_nan = nan,
  dump_number = 65536,
  dump_function = function: 0x115f4d7a0,
  dump_boolean = true,
}

つかいかた

  • 読み込み

こんな感じでrequireしインスタンスを生成します。newの引数はログに接頭で付くので、クラス名をパッケージフルパスで入れておくと便利です。

local log = ( require "log" ).new( "main" );
  • ログの出力

ログの出力はレベルに応じて4種設定され、それぞれ1つずつタブインデントが付いて出力されます。
循環参照やuserdataはオーバーフローするので入れないようにしてください。

log.debug( value ); --なんとなく見たい値とか
log.info( value );  --フロー追いかけ用とか
log.warn( value );  --ちょっとおっかない箇所の出力
log.error( value ); --エラー時用の出力
  • ログレベルの振り分け

ログの出力レベルは、log.luaのlogLevelで変更出来ます。DEBUG/INFO/WARN/ERROR/RELEASEの5段階あり、しきい値以下のレベルは出力されなくなります。
RELEASEに設定すると、一切出力されません。(リリースビルド向け)

log.lua11行目
--しきい値設定
local logLevel = DEBUG;
  • ログディスプレイ表示

実機でしか確認出来ない事項用(GameCenterとかStore関連等)向けに、テキストフィールドにログを出力します。
log.showDisplay()を実行すると、画面の左上に赤と青のボタンが並びます。
・赤ボタン - テキストフィールドの表示ON/OFF
・青ボタン - テキストフィールドの内容を消去(ログが溜まってくると重くなるので、そんな時に)

log.showDisplay();  --引数設定でカラー変化。詳しくはコード見て

--displayList最前面とかにする場合は以下な感じで
--group:insert( log.log_display );

Corona始めて一番最初に書いたコードなので、ちょっと汚いかもしれませんです。

4
4
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
4
4