Check (日本語)

この関数は指定された引数の検査を行い何らかの誤りがある場合にエラー関数を呼び出します。最終的に誤りまたは不正形式の引数がある自作関数を呼び出すときに有用なエラー・メッセージを取得できるためデバッグが容易になります。

書式

void Check( string funcname, var types1, var arg1, string argname1, [ ... ] )

必要な引数

  • funcname: Check 関数を呼び出す関数の名称。
  • types1: arg1 にするべき/かもしれない型。型が一つだけ利用可能は string (文字列) であり、それ以外は文字列型のテーブルです。利用可能な型は "nil", "boolean", "number", "string", "function", "table", "thread" および "userdata" です。
  • arg1: 検査を行う引数の値。
  • argname1: arg1 の値として指定する引数の名前。

選択制の引数

  • ...: 必要であれば三つ以上の引数を渡しても構いません。

ソース

function Check(funcname, ...)
    local arg = {...}
 
    if (type(funcname) ~= "string") then
        error("Argument type mismatch at 'Check' ('funcname'). Expected 'string', got '"..type(funcname).."'.", 2)
    end
    if (#arg % 3 > 0) then
        error("Argument number mismatch at 'Check'. Expected #arg % 3 to be 0, but it is "..(#arg % 3)..".", 2)
    end
 
    for i=1, #arg-2, 3 do
        if (type(arg[i]) ~= "string" and type(arg[i]) ~= "table") then
            error("Argument type mismatch at 'Check' (arg #"..i.."). Expected 'string' or 'table', got '"..type(arg[i]).."'.", 2)
        elseif (type(arg[i+2]) ~= "string") then
            error("Argument type mismatch at 'Check' (arg #"..(i+2).."). Expected 'string', got '"..type(arg[i+2]).."'.", 2)
        end
 
        if (type(arg[i]) == "table") then
            local aType = type(arg[i+1])
            for _, pType in next, arg[i] do
                if (aType == pType) then
                    aType = nil
                    break
                end
            end
            if (aType) then
                error("Argument type mismatch at '"..funcname.."' ('"..arg[i+2].."'). Expected '"..table.concat(arg[i], "' or '").."', got '"..aType.."'.", 3)
            end
        elseif (type(arg[i+1]) ~= arg[i]) then
            error("Argument type mismatch at '"..funcname.."' ('"..arg[i+2].."'). Expected '"..arg[i].."', got '"..type(arg[i+1]).."'.", 3)
        end
    end
end

用例

この用例は Check 関数の使用方法として多かれ少なかれ役に立たない除算関数の場合を示します。

function divide(dividend, divisor, round)
    -- 渡された引数を検査します。
    Check("divide", "number", dividend, "dividend", "number", divisor, "divisor", {"nil","boolean"}, round, "round")

    -- divisor が 0 であればエラーです。
    if (divisor == 0) then error("Someone tried to divide by 0. YOU MUST NOT DO THAT!!!") end

    -- 結果の計算。
    local quotient = dividend / divisor
    -- round が true ならば round の結果になります。
    if (round) then quotient = math.floor(quotient + .5)

    -- 結果を返します。
    return quotient
end