この第 1 版は Lua 5.0 向けに書かれました。後のバージョンでもほとんど内容に違いはありませんが、いくつかの差異があります。
第 4 版は Lua 5.3 をターゲットとしており、Amazon やその他の書店で購入できます。
この本を購入することで、Lua プロジェクトのサポートにも協力していただけます。
![]() |
Programming inLua | ![]() |
パート I. 言語 第 8 章. コンパイル、実行、エラー |
人間は過ちを犯す生き物。したがって、エラーを最善の方法で処理する必要があります。Lua は拡張言語であり、多くの場合、アプリケーションに埋め込まれるため、エラーが発生すると単にクラッシュしたり終了したりすることはできません。その代わり、エラーが発生するたびに、Lua は現在のチャンクを終了し、アプリケーションに戻ります。
Lua が遭遇する予期しない条件はすべて、エラーを引き起こします。数値ではない値の加算、関数ではない値の呼び出し、テーブルではない値のインデックス指定などを試行するとエラーが発生します。(後述のように、メタテーブルを使用してこの動作を変更できます。)また、error
関数を呼び出すことで明示的にエラーを発生させることもできます。その引数はエラーメッセージです。通常、この関数はコード内のエラーを処理するための適切な方法です
print "enter a number:" n = io.read("*number") if not n then error("invalid input") end
if not ... then error end
のような組み合わせは非常に一般的であるため、Lua には assert
というそのジョブ専用の組み込み関数があります。print "enter a number:" n = assert(io.read("*number"), "invalid input")
assert
関数は、最初の引数が偽でないかどうかを確認し、単にその引数を返します。引数が偽の場合(つまり false または nil)、assert
はエラーを発生させます。2 番目の引数のメッセージはオプションなので、エラーメッセージで何も言いたくない場合はその必要はありません。ただし、assert
は通常の関数であることに注意してください。それゆえ、Lua は関数を呼び出す前に常に引数を評価します。したがって、次のようなものがあるとします。n = io.read() assert(tonumber(n), "invalid input: " .. n .. " is not a number")
n
が数値の場合でも、Lua は常に連結を実行します。このような場合は、明示的なテストを使用する方が賢明です。関数が予期しない状況(例外)を見つけた場合、2 つの基本的な動作を想定できます。それはエラーコード(通常は nil)を返すか、error
関数を呼び出してエラーを発生させることができます。これらの 2 つのオプションを選択するための決まりはありませんが、一般的なガイドラインを示すことができます。簡単に回避できる例外はエラーを発生させるべきですが、それ以外の場合はエラーコードを返す必要があります。
例えば、sin
関数を考えてみましょう。テーブルで呼び出された場合、どのように動作する必要がありますか?エラーコードを返すとします。エラーをチェックする必要がある場合は、次のように記述する必要があります。
local res = math.sin(x) if not res then -- error ...ただし、関数を呼び出す前にこの例外を容易にチェックできます。
if not tonumber(x) then -- error: x is not a number ...ただし、通常は
sin
の引数も結果もチェックしません。引数が数値でない場合、おそらくプログラムに何か問題があることを意味します。このような状況では、計算を停止してエラーメッセージを発行するのが、例外を処理するための最も簡単で実用的な方法です。それに対し、ファイルを開く io.open
関数について考えてみましょう。存在しないファイルをよみこもうとした場合、関数はどのように動作すべきでしょうか? この場合、関数をよびだすまえに例外をチェックする簡単な方法は存在しません。多くのシステムでは、ファイルが存在するかを確認する唯一の方法は、ファイルを開こうとすることです。したがって、 io.open
が外部的な理由(例えば "ファイルが存在しません"
や "アクセスが拒否されました"
)によりファイルをひらけない場合、nilと、エラーメッセージを含む文字列が返されます。この方法を使うことで、たとえばユーザーに別のファイル名を入力させることによって、状況を適切に処理する機会を得ることができます
local file, msg repeat print "enter a file name:" local name = io.read() if not name then return end -- no input file, msg = io.open(name, "r") if not file then print(msg) end until fileこのような状況に対処したくないのであれば、でも安全側にいたいというのであれば、単に
assert
を使って操作を保護してくださいfile = assert(io.open(name, "r"))これは典型的なLuaの慣用句です:
io.open
が失敗すると、 assert
はエラーを出すことになります。file = assert(io.open("no-file", "r")) --> stdin:1: no-file: No such file or directory
io.open
からの2番目の結果であるエラーメッセージが、 assert
への2番目の引数になることに注意してください。著作権 © 2003–2004 Roberto Ierusalimschy。すべての権利を保有します。 | ![]() |