Lua-エラー処理

エラー処理の必要性

実際の操作では、ファイル操作、データベーストランザクション、Webサービス呼び出しなどの複雑な操作を使用する必要があることが多いため、エラー処理は非常に重要です。

どのプログラミングでも、エラー処理の要件は常にあります。エラーには、次の2つのタイプがあります。

  • 構文エラー
  • 実行時エラー

構文エラー

演算子や式などのさまざまなプログラムコンポーネントの不適切な使用により、構文エラーが発生します。構文エラーの簡単な例を以下に示します。

a == 2

ご存知のように、シングル「等しい」とダブル「等しい」の使用には違いがあります。一方を他方の代わりに使用すると、エラーが発生する可能性があります。1つの「等しい」は割り当てを示し、2つの「等しい」は比較を示します。同様に、事前定義された実装方法を持つ式と関数があります。

構文エラーの別の例を以下に示します-

for a= 1,10
   print(a)
end

上記のプログラムを実行すると、次の出力が得られます-

lua: test2.lua:2: 'do' expected near 'print'

Luaインタープリターはランタイムエラーの場合よりも明確にエラーを特定するため、構文エラーはランタイムエラーよりもはるかに簡単に処理できます。上記のエラーから、Lua構造に従って、printステートメントの前にdoステートメントを追加する必要があることが簡単にわかります。

実行時エラー

ランタイムエラーの場合、プログラムは正常に実行されますが、入力の誤りや関数の取り扱いミスにより、ランタイムエラーが発生する可能性があります。実行時エラーを示す簡単な例を以下に示します。

function add(a,b)
   return a+b
end

add(10)

プログラムをビルドすると、正常にビルドされて実行されます。実行すると、実行時エラーが表示されます。

lua: test2.lua:2: attempt to perform arithmetic on local 'b' (a nil value)
stack traceback:
	test2.lua:2: in function 'add'
	test2.lua:5: in main chunk
	[C]: ?

これは、2つの変数を渡さなかったために発生したランタイムエラーです。ザ・b パラメータが必要ですが、ここではnilであり、エラーが発生します。

アサートおよびエラー関数

エラーを処理するために、2つの関数を使用することがよくあります- assert そして error。簡単な例を以下に示します。

local function add(a,b)
   assert(type(a) == "number", "a is not a number")
   assert(type(b) == "number", "b is not a number")
   return a+b
end

add(10)

上記のプログラムを実行すると、次のエラー出力が表示されます。

lua: test2.lua:3: b is not a number
stack traceback:
	[C]: in function 'assert'
	test2.lua:3: in function 'add'
	test2.lua:6: in main chunk
	[C]: ?

ザ・ error (message [, level])最後に呼び出された保護された関数を終了し、メッセージをエラーメッセージとして返します。この関数エラーは返されません。通常、errorは、メッセージの先頭にエラー位置に関する情報を追加します。level引数は、エラー位置を取得する方法を指定します。レベル1(デフォルト)では、エラー位置はエラー関数が呼び出された場所です。レベル2は、エラーを呼び出した関数が呼び出された場所にエラーを示します。等々。レベル0を渡すと、メッセージへのエラー位置情報の追加が回避されます。

pcallとxpcall

Luaプログラミングでは、これらのエラーのスローやエラーの処理を回避するために、関数pcallまたはxpcallを使用する必要があります。

ザ・ pcall (f, arg1, ...)関数は、プロテクトモードで要求された関数を呼び出します。関数fでエラーが発生しても、エラーはスローされません。エラーのステータスを返すだけです。pcallを使用した簡単な例を以下に示します。

function myfunction ()
   n = n/nil
end

if pcall(myfunction) then
   print("Success")
else
	print("Failure")
end

上記のプログラムを実行すると、次の出力が得られます。

Failure

ザ・ xpcall (f, err)関数は要求された関数を呼び出し、エラーハンドラーも設定します。f内のエラーは伝播されません。代わりに、xpcallはエラーをキャッチし、元のエラーオブジェクトを使用してerr関数を呼び出し、ステータスコードを返します。

xpcallの簡単な例を以下に示します。

function myfunction ()
   n = n/nil
end

function myerrorhandler( err )
   print( "ERROR:", err )
end

status = xpcall( myfunction, myerrorhandler )
print( status)

上記のプログラムを実行すると、次の出力が得られます。

ERROR:	test2.lua:2: attempt to perform arithmetic on global 'n' (a nil value)
false

プログラマーとして、あなたが書くプログラムで適切なエラー処理に注意を払うことを確実にすることが最も重要です。エラー処理を使用すると、プログラムのユーザーの邪魔をすることなく、境界条件を超える予期しない条件を確実に処理できます。