Lua 5.2 リファレンスマニュアル
執筆者: Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
著作権 © 2011–2013 Lua.org, PUC-Rio. Luaライセンスの条件のもと、無料で提供されています。
1 - はじめに
Luaは、データ記述の機能を備えた汎用的な手続き型プログラミングをサポートする拡張プログラミング言語です。また、オブジェクト指向プログラミング、関数型プログラミング、データ駆動型プログラミングにも優れたサポートを提供しています。Luaは、スクリプト言語を必要とする任意のプログラムのための、強力かつ軽量で埋め込み可能なスクリプト言語として設計されています。LuaはクリーンなCコードで書かれたライブラリとして実装されており、Standard CとC++の共通部分で構成されています。
Luaは拡張言語であるため、「メイン」プログラムという概念はありません。常にホストとなるクライアントプログラム内で埋め込まれ、その中で動作します。ホストプログラムはLuaコードを実行するために関数を呼び出したり、Luaの変数を読み書きしたり、Luaコードから呼び出されるC関数を登録したりすることができます。C関数を使用することで、Luaは多様な領域に対応できるように拡張でき、同じ構文フレームワークを共有するカスタマイズされたプログラミング言語を作成できます。Luaの配布には、Luaライブラリを利用して対話型またはバッチ処理に対応する完全な独立したLuaインタプリタである「lua」というサンプルホストプログラムが含まれています。
Luaはフリーソフトウェアであり、通常の保証はなく、ライセンスに明記された通り提供されます。このマニュアルで説明されている実装は、Luaの公式ウェブサイト www.lua.org で入手可能です。
この文書は他のリファレンスマニュアルと同様、読みにくい箇所があるかもしれません。Luaの設計に関する決定については、Luaのウェブサイトにある技術論文を参照してください。また、Luaでのプログラミングに関する詳細な入門書として、Robertoの著書『Programming in Lua』があります。
2 - 基本概念
このセクションでは、Lua言語の基本的な概念について説明します。
2.1 - 値と型
Luaは動的型付け言語です。これは、変数自体に型がないことを意味し、型は値にのみ関連付けられます。言語内に型の定義は存在せず、すべての値はその型情報を持っています。
Luaのすべての値は「第一級の値」です。つまり、すべての値は変数に格納でき、他の関数への引数として渡したり、結果として返したりすることができます。
Luaには8つの基本的な型があります: nil、boolean、number、string、function、userdata、thread、および table です。nilは、他のすべての値と異なる特性を持ち、通常は有効な値がないことを示します。booleanはfalseとtrueの値を持つ型で、nilとfalseは条件をfalseにし、他の値はすべてtrueにします。numberは実数(倍精度浮動小数点数)を表します。数値に対する操作は、通常IEEE 754規格に準拠しているCの実装ルールに従います。(単精度浮動小数点数や長整数など、他の内部表現を使用するLuaインタプリタも簡単に作成できます。詳細はluaconf.hファイルを参照してください)。stringは不変のバイト列を表します。Luaは8ビットに対応しているため、文字列には埋め込みゼロ(\0)を含む任意の8ビット値が含まれます。
Luaは、Luaで書かれた関数とCで書かれた関数の両方を呼び出し操作できます(詳細は§3.4.9を参照してください)。
userdata型は、任意のCデータをLua変数に格納するために提供されており、userdata値は生のメモリブロックへのポインタです。userdataには、Luaによって管理されるフルuserdataと、ホストによって管理される軽量userdataの2種類があります。userdataにはLua内で事前定義された操作はなく、代入と同一性テストのみがサポートされています。メタテーブルを使用することで、プログラマはフルuserdataに対する操作を定義できます(詳細は§2.4を参照してください)。userdataはLua内で生成または変更できず、C APIを通じてのみ操作可能です。これにより、ホストプログラムが所有するデータの整合性が保証されます。
thread型は独立した実行スレッドを表し、コルーチンを実装するために使用されます(詳細は§2.6を参照してください)。Luaのスレッドとオペレーティングシステムのスレッドは異なるものです。Luaは、OSのスレッドサポートがないシステムでもコルーチンを利用できます。
table型は、連想配列(配列のインデックスに数字だけでなく、任意のLua値(ただしnilとNaNを除く)を使用できる配列)を実装します。tableは異種データ(異なる型の値)を含むことができ、キーの値がnilのエントリはテーブルの一部とみなされません。反対に、テーブルの一部でないキーにはnilの値が関連付けられます。
Luaにおけるtableは唯一のデータ構造化機構であり、通常の配列、シーケンス、シンボルテーブル、集合、レコード、グラフ、ツリーなどを表現できます。レコードを表現するために、Luaではフィールド名をインデックスとして使用します。この言語ではa.nameという記法をa["name"]の簡略形として提供しています。Luaにはテーブルを作成するための便利な方法がいくつかあります(詳細は§3.4.8を参照してください)。
シーケンスという用語は、{1..n}という形で全ての正の数値キーを持つテーブルを指し、nはシーケンスの長さと呼ばれます(詳細は§3.4.6を参照してください)。
テーブルのフィールドの値は、関数が第一級の値であるため、任意の型であることができます。したがって、テーブルにはメソッド(関数)を含めることができます(詳細は§3.4.10を参照してください)。
テーブルのインデックスは、Luaの生の等価性定義に従います。式a[i]とa[j]は、iとjが生で等しい(メタメソッドを使用しない等価である)場合にのみ同じテーブル要素を指します。
テーブル、関数、スレッド、そして(フル)userdataの値は「オブジェクト」です。これらの値を変数に直接含むのではなく、参照として扱います。代入、パラメータの受け渡し、および関数の戻り値は常に参照を操作し、これらの操作はコピーを伴いません。
ライブラリ関数typeは、指定された値の型を示す文字列を返します(詳細は§6.1を参照してください)。
2.2 - 環境とグローバル環境
§3.2と§3.3.3で詳しく説明されるように、グローバル名 var への参照は、構文的に _ENV.var へと変換されます。また、すべてのチャンク(Luaコードの一塊)は、外部のローカル変数 _ENV のスコープ内でコンパイルされるため(§3.3.2参照)、チャンク内で _ENV 自体がグローバル名になることはありません。
この外部変数 _ENV の存在やグローバル名の変換にもかかわらず、_ENV は通常の変数名として扱えます。具体的には、この名前で新しい変数やパラメータを定義することができます。プログラム内でグローバル名にアクセスするときには、Luaの通常の可視性ルールに従って、その時点で見える _ENV が使用されます(§3.5参照)。
_ENV に割り当てられたテーブルは「環境」と呼ばれます。
Luaは「グローバル環境」と呼ばれる特別な環境を保持しています。この値は、Cレジストリ内の特別なインデックスに保持されます(§4.5参照)。Luaでは、このグローバル環境と同じ値で変数 _G が初期化されます。
Luaがチャンクをコンパイルする際、そのチャンクの _ENV アップバリュー(上位値)をグローバル環境で初期化します(load 参照)。したがって、デフォルトでは、Luaコード内のグローバル変数はグローバル環境のエントリを参照します。また、すべての標準ライブラリはグローバル環境にロードされており、いくつかの関数はこの環境で操作を行います。load や loadfile を使用すると、異なる環境でチャンクを読み込むことができます。(C言語では、チャンクを読み込んだ後で最初のアップバリューの値を変更する必要があります)。
Cコードやデバッグライブラリを通じてレジストリ内のグローバル環境を変更すると、変更後に読み込まれたチャンクは新しい環境を取得します。しかし、以前に読み込まれたチャンクには影響がありません。これは、それぞれが自身の _ENV 変数内に環境への参照を持っているためです。また、Luaは変数 _G(元のグローバル環境に格納されている)を更新しません。
2.3 - エラーハンドリング
Luaは埋め込み型の拡張言語であるため、すべてのLuaの動作はホストプログラム内のCコードがLuaライブラリからの関数を呼び出すことから始まります(lua_pcall参照)。Luaチャンクのコンパイルや実行中にエラーが発生すると、制御はホストプログラムに戻され、適切な処理(例: エラーメッセージの表示)を行うことができます。
Luaコード内で明示的にエラーを発生させるには、error 関数を使用します。Luaでエラーをキャッチする必要がある場合、pcall または xpcall を使って特定の関数を保護モードで呼び出すことができます。
エラーが発生すると、エラーに関する情報を持ったエラーオブジェクト(エラーメッセージとも呼ばれます)が伝播されます。Lua自体はエラーオブジェクトが文字列のエラーのみを生成しますが、プログラムはエラーオブジェクトに任意の値を使用してエラーを生成することが可能です。
xpcall または lua_pcall を使用する際、エラー発生時に呼び出されるメッセージハンドラを指定することができます。この関数は元のエラーメッセージを受け取り、新しいエラーメッセージを返します。この関数はエラーがスタックを巻き戻す前に呼び出されるため、スタックのトレースバックを生成するなど、エラーに関するさらなる情報を収集できます。このメッセージハンドラも保護された呼び出しによって保護されるため、メッセージハンドラ内でエラーが発生すると再びメッセージハンドラが呼ばれます。このループが続くと、Luaはそれを停止し、適切なメッセージを返します。
2.4 - メタテーブルとメタメソッド
Luaのすべての値はメタテーブルを持つことができます。メタテーブルは通常のLuaテーブルで、特定の操作時に元の値の動作を定義します。メタテーブルの特定のフィールドを設定することで、値に対する操作のいくつかの挙動を変更できます。例えば、数値でない値を足し算の演算子のオペランドとして使用すると、Luaはその値のメタテーブルの"__add"フィールドに関数があるかどうかを確認します。関数が見つかれば、その関数が足し算を実行します。
メタテーブルのキーはイベント名から派生しており、対応する値はメタメソッドと呼ばれます。前述の例では、イベントは"add"で、メタメソッドは足し算を行う関数です。
メタテーブルはgetmetatable関数で確認できます。
テーブルのメタテーブルはsetmetatable関数で置き換えることができますが、他の型のメタテーブルはLuaから変更できません(デバッグライブラリを除く)。これにはC APIを使用する必要があります。
テーブルとフルユーザデータは個別のメタテーブルを持つことができますが、他のすべての型は同じ型の値で1つのメタテーブルを共有します。つまり、すべての数値や文字列に対して1つのメタテーブルが存在します。デフォルトでは値にメタテーブルはありませんが、文字列ライブラリは文字列型にメタテーブルを設定します(§6.4参照)。
メタテーブルは、算術演算、順序比較、連結、長さ操作、インデックス参照時のオブジェクトの挙動を制御できます。また、ユーザデータやテーブルがガベージコレクションされる際に呼び出される関数も定義できます。Luaがこれらの操作を値に対して実行する際、その値に対応するイベントのメタメソッドがあるメタテーブルが存在するかを確認します。存在する場合、Luaはそのメタメソッドを使用して操作を行います。
以下に挙げる操作はメタテーブルによって制御されます。各操作には対応する名前があり、キーにはその名前の前に2つのアンダースコア「__」が付けられています。例えば、「add」操作のキーは文字列"__add"です。
操作の詳細な説明として、Luaインタープリタが操作をどのように実行するかを示すLua関数を用います。ここに示すLuaコードはあくまで説明用で、実際の動作はインタープリタにハードコードされており、はるかに効率的です。説明で使用する関数(rawget、tonumberなど)は§6.1で説明されています。特に、あるオブジェクトのメタメソッドを取得するには以下の表現を使用します:
metatable(obj)[event]
これは次のように解釈されます:
rawget(getmetatable(obj) or {}, event)
これにより、メタメソッドへのアクセスが他のメタメソッドを呼び出さず、メタテーブルのないオブジェクトへのアクセスがエラーとならずにnilを返します。
単項の「-」や「#」演算子の場合、メタメソッドはダミーの第2引数と共に呼び出されます。この追加引数はLuaの内部処理を簡素化するためのものであり、将来のバージョンで削除される可能性があるため、以下のコードには含まれていません。(ほとんどの場合、この追加引数は無関係です。)
"add":
+演算。以下のgetbinhandler関数は、Luaが二項演算のためのハンドラをどのように選択するかを定義します。最初に第1オペランドを確認し、その型にハンドラが定義されていない場合は第2オペランドを確認します。luafunction getbinhandler (op1, op2, event) return metatable(op1)[event] or metatable(op2)[event] endこの関数を使用すると、
op1 + op2の動作は次のようになります:luafunction add_event (op1, op2) local o1, o2 = tonumber(op1), tonumber(op2) if o1 and o2 then -- 両方のオペランドが数値か? return o1 + o2 -- "+" はここで基本の "add" 演算 else -- 少なくとも一方のオペランドが数値でない場合 local h = getbinhandler(op1, op2, "__add") if h then -- 両オペランドを引数にしてハンドラを呼び出す return (h(op1, op2)) else -- ハンドラが見つからない場合: デフォルトの挙動 error("エラー") end end end"sub":
-演算。add演算と同様の動作です。"mul":
*演算。add演算と同様の動作です。"div":
/演算。add演算と同様の動作です。"mod":
%演算。add演算と同様ですが、基本の演算はo1 - floor(o1 / o2) * o2です。"pow":
^(べき乗)演算。add演算と同様ですが、基本の演算はCのmathライブラリにあるpow関数です。"unm": 単項
-演算。luafunction unm_event(op) local o = tonumber(op) if o then -- オペランドが数値か? return -o -- '-' はここで基本の "unm" 演算 else -- オペランドが数値でない場合 local h = metatable(op).__unm if h then -- オペランドを引数にしてハンドラを呼び出す return (h(op)) else -- ハンドラが見つからない場合: デフォルトの挙動 error("エラー") end end end"concat":
..(連結)演算。luafunction concat_event(op1, op2) if (type(op1) == "string" or type(op1) == "number") and (type(op2) == "string" or type(op2) == "number") then return op1 .. op2 -- 基本の文字列連結 else local h = getbinhandler(op1, op2, "__concat") if h then return (h(op1, op2)) else error("エラー") end end end"len":
#(長さ)演算。luafunction len_event(op) if type(op) == "string" then return strlen(op) -- 基本の文字列長 else local h = metatable(op).__len if h then return (h(op)) -- ハンドラをオペランドと共に呼び出す elseif type(op) == "table" then return #op -- 基本のテーブルの長さ else -- ハンドラが見つからない場合: エラー error("エラー") end end endテーブルの長さに関する詳細は、§3.4.6を参照してください。
"eq":
==(等価)演算。getequalhandler関数はLuaが等価のためのメタメソッドをどのように選択するかを定義します。比較される両方の値が同じ型を持ち、比較される操作に同じメタメソッドを持つ場合のみ、メタメソッドが選択されます。また、比較対象の値はテーブルまたはフルユーザデータでなければなりません。luafunction getequalhandler(op1, op2) if type(op1) ~= type(op2) or (type(op1) ~= "table" and type(op1) ~= "userdata") then return nil -- 異なる値 end local mm1 = metatable(op1).__eq local mm2 = metatable(op2).__eq if mm1 == mm2 then return mm1 else return nil end end**"eq"**イベントは以下のように定義されています:
luafunction eq_event(op1, op2) if op1 == op2 then -- 基本の等価判定 return true -- 値が等しい end -- メタメソッドを試す local h = getequalhandler(op1, op2) if h then return not not h(op1, op2) else return false end end結果は常にブール値です。
"lt":
<(小なり)演算。luafunction lt_event(op1, op2) if type(op1) == "number" and type(op2) == "number" then return op1 < op2 -- 数値の比較 elseif type(op1) == "string" and type(op2) == "string" then return op1 < op2 -- 辞書順比較 else local h = getbinhandler(op1, op2, "__lt") if h then return not not h(op1, op2) else error("エラー") end end end結果は常にブール値です。
"le":
<=(小なりまたは等しい)演算。luafunction le_event(op1, op2) if type(op1) == "number" and type(op2) == "number" then return op1 <= op2 -- 数値の比較 elseif type(op1) == "string" and type(op2) == "string" then return op1 <= op2 -- 辞書順比較 else local h = getbinhandler(op1, op2, "__le") if h then return not not h(op1, op2) else h = getbinhandler(op1, op2, "__lt") if h then return not h(op2, op1) else error("エラー") end end end end"le"メタメソッドが存在しない場合、Luaは"lt"メタメソッドを試み、
a <= bをnot (b < a)として扱います。他の比較演算子と同様、結果は常にブール値です。"index": インデックス参照
table[key]。keyがテーブルに存在しない場合のみメタメソッドが呼ばれます。(tableがテーブルでない場合、どのキーも存在しないためメタメソッドは常に試行されます。)luafunction gettable_event(table, key) local h if type(table) == "table" then local v = rawget(table, key) -- キーが存在すれば、未加工の値を返す if v ~= nil then return v end h = metatable(table).__index if h == nil then return nil end else h = metatable(table).__index if h == nil then error("エラー") end end if type(h) == "function" then return (h(table, key)) -- ハンドラを呼び出す else return h[key] -- またはハンドラに対して操作を繰り返す end end"newindex": インデックス代入
table[key] = value。keyがテーブルに存在しない場合のみメタメソッドが呼ばれます。luafunction settable_event(table, key, value) local h if type(table) == "table" then local v = rawget(table, key) -- キーが存在すれば、未加工の代入を行う if v ~= nil then rawset(table, key, value); return end h = metatable(table).__newindex if h == nil then rawset(table, key, value); return end else h = metatable(table).__newindex if h == nil then error("エラー") end end if type(h) == "function" then h(table, key, value) -- ハンドラを呼び出す else h[key] = value -- またはハンドラに対して操作を繰り返す end end"call": Luaが値を呼び出すときに使用されます。
luafunction function_event(func, ...) if type(func) == "function" then return func(...) -- 基本の呼び出し else local h = metatable(func).__call if h then return h(func, ...) else error("エラー") end end end
2.5 - ガベージコレクション
Luaは自動メモリ管理を行います。つまり、新しいオブジェクトのためにメモリを割り当てたり、不要になったオブジェクトのメモリを解放したりすることを気にする必要はありません。Luaはガベージコレクタを実行して、不要なオブジェクト(Luaからアクセスできなくなったオブジェクト)をすべて収集することでメモリを自動管理します。Luaが使用するすべてのメモリ(文字列、テーブル、ユーザデータ、関数、スレッド、内部構造など)は、自動管理の対象です。
Luaは増分マーク&スイープ方式のガベージコレクタを実装しています。このガベージコレクションサイクルを制御するために、ガベージコレクタの「ポーズ」と「ステップ倍率」という2つの数値を使用します。どちらも単位はパーセントで表されます(例: 値100は内部的に1を意味します)。
ガベージコレクタのポーズは、新しいサイクルを開始する前にガベージコレクタが待機する時間を制御します。値が大きいほどガベージコレクタは控えめに動作します。100未満の値ではガベージコレクタが待機せずに新しいサイクルを開始します。値が200の場合、使用メモリが2倍になるまで待機してから新しいサイクルを開始します。
ガベージコレクタのステップ倍率は、メモリ割り当てに対するガベージコレクタの相対速度を制御します。値が大きいほどガベージコレクタは積極的に動作しますが、各増分ステップのサイズも大きくなります。100未満の値ではガベージコレクタが遅くなりすぎ、サイクルを完了できない可能性があります。デフォルトは200で、これはガベージコレクタがメモリ割り当ての「2倍」の速度で実行されることを意味します。
ステップ倍率を非常に大きな数値(プログラムで使用可能な最大バイト数の10%以上)に設定すると、ガベージコレクタはストップ・ザ・ワールド(全停止)コレクタのように動作します。さらにポーズを200に設定すると、ガベージコレクタは古いLuaバージョンのように動作し、Luaがメモリ使用量を2倍にするたびに完全なコレクションを実行します。
これらの数値は、C言語のlua_gcまたはLuaのcollectgarbage関数を使って変更できます。また、これらの関数を使用してガベージコレクタを直接制御することも可能です(例: 停止や再開など)。
Lua 5.2では実験的な機能として、コレクタの動作モードを増分型から世代別型に変更することができます。世代別ガベージコレクタは、大半のオブジェクトが生成後すぐに不要になると仮定し、新しい(最近生成された)オブジェクトだけを処理します。この動作によりガベージコレクタの使用時間が減少する可能性がありますが、メモリ使用量は増加する場合があります(古い不要なオブジェクトが蓄積される可能性があるためです)。この問題を軽減するため、世代別ガベージコレクタは定期的に完全なコレクションを実行します。この機能は実験的なものであることを忘れず、試してみることは可能ですが、その効果を確認してください。
2.5.1 - ガベージコレクションのメタメソッド
テーブルや、C APIを使用したフルユーザデータ(§2.4参照)にガベージコレクションのメタメソッドを設定することができます。これらのメタメソッドは「ファイナライザ」とも呼ばれます。ファイナライザを使用すると、Luaのガベージコレクションと外部リソース管理(例: ファイル、ネットワークやデータベース接続の終了、自分で確保したメモリの解放など)を連携させることができます。
オブジェクト(テーブルまたはユーザデータ)をコレクション時にファイナライズ(終了処理)するためには、ファイナライズ用にマークする必要があります。ファイナライズ用にオブジェクトをマークするには、メタテーブルを設定し、そのメタテーブルに"__gc"というインデックスのフィールドを持たせます。なお、__gcフィールドがないメタテーブルを設定し、その後でそのフィールドをメタテーブルに追加した場合、オブジェクトはファイナライズ用にマークされません。しかし、一度オブジェクトがマークされると、そのメタテーブルの__gcフィールドは自由に変更できます。
マークされたオブジェクトがガベージになったとき、ガベージコレクタによってすぐに回収されるわけではありません。Luaはそのオブジェクトをリストに追加し、コレクション後にリスト内の各オブジェクトに対して以下のような関数を実行します:
```lua
function gc_event (obj)
local h = metatable(obj).__gc
if type(h) == "function" then
h(obj)
end
end
```
各ガベージコレクションサイクルの終了時に、ファイナライズが必要なオブジェクトのファイナライザが、サイクル内で回収された順に逆順で呼び出されます。つまり、プログラム内で最後にマークされたオブジェクトに関連するファイナライザが最初に呼び出されます。各ファイナライザの実行は、通常のコードの実行中の任意のポイントで行われることがあります。
収集されているオブジェクトはファイナライザで使用されるため、(およびファイナライザを通じてのみアクセス可能な他のオブジェクトも)一時的にLuaによって復活(リザレクション)されなければなりません。通常、この復活は一時的であり、次のガベージコレクションサイクルでオブジェクトメモリは解放されます。しかし、ファイナライザがオブジェクトをグローバルな場所(例: グローバル変数)に格納した場合は、オブジェクトが永続的に復活します。いずれの場合も、オブジェクトが完全にアクセスできなくなったときにのみメモリが解放され、ファイナライザが2回呼び出されることはありません。
状態を閉じるとき(lua_close参照)、Luaはファイナライズ対象にマークされたすべてのオブジェクトのファイナライザを、マークされた順序の逆順で呼び出します。この段階でファイナライザが新しいオブジェクトを収集対象にマークした場合、それらの新しいオブジェクトはファイナライズされません。
2.5.2 - 弱テーブル
弱テーブルとは、要素が弱参照であるテーブルのことです。弱参照はガベージコレクタによって無視されます。つまり、オブジェクトへの参照が弱参照のみの場合、ガベージコレクタはそのオブジェクトを回収します。
弱テーブルには、キーが弱参照のもの、値が弱参照のもの、または両方が弱参照のものがあります。キーが弱いテーブルではキーの回収が可能になりますが、値の回収は防止されます。一方、キーと値の両方が弱いテーブルでは、どちらも回収可能です。いずれの場合も、キーまたは値のいずれかが回収されると、そのペア全体がテーブルから削除されます。テーブルの弱さはメタテーブルの__modeフィールドで制御されます。__modeフィールドが文字'k'を含む文字列であれば、テーブルのキーは弱くなります。__modeが'v'を含む場合、テーブルの値は弱くなります。
キーが弱く値が強いテーブルは「エフェメロンテーブル」とも呼ばれます。エフェメロンテーブルでは、キーが到達可能な場合のみその値が到達可能と見なされます。特に、キーへの唯一の参照が値からの場合、そのペアは削除されます。
テーブルの弱さを変更しても、その効果が現れるのは次のコレクションサイクルからです。特に、弱さを強く変更した場合でも、変更が反映される前にLuaがそのテーブルからいくつかの項目を回収する可能性があります。
明示的な構築があるオブジェクトのみが弱テーブルから削除されます。数値や軽量C関数のような値はガベージコレクションの対象ではないため、弱テーブルから削除されません(ただし、関連する値が回収された場合は例外です)。文字列はガベージコレクションの対象ですが、明示的な構築がないため、弱テーブルからは削除されません。
復活したオブジェクト(ファイナライズ中のオブジェクトや、ファイナライズ中のオブジェクトを介してのみアクセス可能なオブジェクト)は、弱テーブルにおいて特別な挙動を示します。これらは、ファイナライザの実行前に弱値から削除されますが、弱キーからはファイナライザの実行後の次のコレクションサイクルまで削除されません。この動作により、ファイナライザが弱テーブルを通じてオブジェクトに関連するプロパティにアクセスできるようになります。
あるコレクションサイクルで復活したオブジェクトの中に弱テーブルが含まれている場合、そのテーブルのクリアが次のサイクルまで適切に行われないことがあります。
2.6 - コルーチン
Luaはコルーチン、または協調的マルチスレッドをサポートしています。Luaにおけるコルーチンは、独立した実行スレッドを表します。ただし、マルチスレッドシステムのスレッドとは異なり、コルーチンはyield関数を明示的に呼び出すことでのみ実行を中断します。
コルーチンはcoroutine.createを呼び出して作成します。この関数の唯一の引数は、コルーチンのメイン関数となる関数です。create関数は新しいコルーチンを作成し、そのハンドル(スレッド型のオブジェクト)を返すだけで、コルーチンを開始するわけではありません。
コルーチンを実行するには、coroutine.resumeを呼び出します。最初にcoroutine.resumeを呼び出す際には、最初の引数にcoroutine.createで返されたスレッドを渡します。すると、コルーチンのメイン関数の最初の行から実行が始まります。coroutine.resumeに渡された追加の引数は、コルーチンのメイン関数に引き継がれます。コルーチンが実行を開始すると、終了または中断するまで動作を続けます。
コルーチンが実行を終了するのは、以下の2通りです:通常の終了(メイン関数が戻り値を返すか、最後の命令を実行した後)または保護されていないエラーの発生による異常終了です。通常終了の場合、coroutine.resumeはtrueと、コルーチンのメイン関数から返された任意の値を返します。エラーが発生した場合は、coroutine.resumeはfalseとエラーメッセージを返します。
コルーチンはcoroutine.yieldを呼び出すことで実行を中断します。コルーチンが中断すると、対応するcoroutine.resumeは即座に戻り、中断がネストされた関数呼び出しの中で(つまり、メイン関数ではなく、メイン関数から直接または間接的に呼び出された関数内で)発生していても、その場所で戻ります。yieldの場合、coroutine.resumeもtrueを返し、さらにcoroutine.yieldに渡された任意の値も返されます。次に同じコルーチンを再開すると、中断した場所から続行され、coroutine.yieldに戻り、coroutine.resumeに渡された追加の引数が返されます。
coroutine.createと同様に、coroutine.wrap関数もコルーチンを作成しますが、コルーチン自体を返す代わりに、それを再開する関数を返します。この関数に渡された任意の引数は、追加の引数としてcoroutine.resumeに渡されます。coroutine.wrapはcoroutine.resumeの返り値をすべて返しますが、最初のブール型のエラーフラグは除きます。coroutine.resumeとは異なり、coroutine.wrapはエラーをキャッチしないため、エラーは呼び出し元に伝播されます。
以下は、コルーチンがどのように動作するかを示す例です:
function foo (a)
print("foo", a)
return coroutine.yield(2 * a)
end
co = coroutine.create(function (a, b)
print("co-body", a, b)
local r = foo(a + 1)
print("co-body", r)
local r, s = coroutine.yield(a + b, a - b)
print("co-body", r, s)
return b, "end"
end)
print("main", coroutine.resume(co, 1, 10))
print("main", coroutine.resume(co, "r"))
print("main", coroutine.resume(co, "x", "y"))
print("main", coroutine.resume(co, "x", "y"))上記のコードを実行すると、以下の出力が得られます:
co-body 1 10
foo 2
main true 4
co-body r
main true 11 -9
co-body x y
main true 10 end
main false cannot resume dead coroutineまた、コルーチンはC APIを通じて作成および操作することも可能です。具体的には、lua_newthread、lua_resume、およびlua_yield関数を使用します。
3 – 言語
このセクションでは、Luaの字句(lexis)、構文(syntax)、および意味(semantics)について説明します。言い換えると、このセクションでは有効なトークンがどれか、それらがどのように組み合わせられるか、およびその組み合わせが何を意味するかについて解説します。
言語の構造は、一般的な拡張BNF記法を使って説明されます。この記法では、{a}は「0回以上のa」、[a]は「任意のa(ある場合とない場合の両方が許容される)」を意味します。非終端記号はnon-terminalのように、キーワードはkwordのように、その他の終端記号は'='のように表示されます。Luaの完全な構文については、このマニュアルの末尾にある§9で確認できます。
3.1 – 字句規則
Luaは自由形式の言語で、スペース(改行も含む)やコメントは字句要素(トークン)間の区切りとして使用される場合を除き無視されます。
Luaの名前(識別子とも呼ばれます)は、文字、数字、およびアンダースコアの組み合わせで構成されますが、最初の文字に数字は使用できません。識別子は変数、テーブルのフィールド、ラベルの名前を定義するために使用されます。
以下のキーワードは予約されており、名前として使用することはできません。
and break do else elseif end
false for function goto if in
local nil not or repeat return
then true until whileLuaは大文字と小文字を区別します。たとえば、andは予約語ですが、AndやANDは別の有効な名前として認識されます。また、慣例として、アンダースコアと大文字で始まる名前(例:_VERSION)はLuaで使用される変数のために予約されています。
以下の文字列はその他のトークンを表します。
+ - * / % ^ #
== ~= <= >= < > =
( ) { } [ ] ::
; : , . .. ...リテラル文字列はシングルクォートまたはダブルクォートで囲むことができ、次のC言語風のエスケープシーケンスを含むことができます:
\a(ベル)\b(バックスペース)\f(改ページ)\n(改行)\r(キャリッジリターン)\t(水平タブ)\v(垂直タブ)\\(バックスラッシュ)\"(ダブルクォート)\'(シングルクォート)
バックスラッシュの後に改行を置くと、文字列内に改行が挿入されます。エスケープシーケンス \z は後に続く空白文字(改行を含む)をスキップします。これは、長いリテラル文字列を複数行に分けてインデントする際、改行やスペースを含めずに見やすくするために便利です。
リテラル文字列内のバイトを数値で指定することも可能です。16進数の2桁を使ったエスケープシーケンス \xXX(例:\x41はASCIIコードの'A')や、最大3桁の10進数を使ったエスケープシーケンス \ddd(例:\065も'A')で指定します。ただし、10進エスケープの後にさらに数字が続く場合は、必ず3桁で指定する必要があります。Luaの文字列は埋め込みゼロ(\0)を含む任意の8ビット値を含むことができます。
リテラル文字列は、長い形式で長い角括弧を使用して定義することもできます。レベルnの開き長角括弧は、開き角括弧[の後にn個の等号=を置き、さらにもう一つの開き角括弧[で囲む形式です。レベル0の開き長角括弧は[[と書き、レベル1は[=[、レベル4なら[====[のように書きます。同様に閉じる角括弧も指定され、例えばレベル4では]====]となります。長いリテラル文字列は、任意のレベルの開き長角括弧で始まり、同じレベルの閉じ長角括弧で終わります。この形式のリテラルは複数行にわたり、エスケープシーケンスを解釈せず、異なるレベルの長角括弧を無視します。行末の改行コード(キャリッジリターンや改行、もしくはそれらの組み合わせ)は単純な改行に変換されます。
リテラル文字列内のバイトは、前述のルールに該当しない限り、そのままの値として扱われます。ただし、Luaはファイルをテキストモードで開いて解析するため、システムのファイル関数が一部の制御文字に問題を起こす可能性があります。そのため、テキスト以外のデータを扱う場合は、引用符で囲んだリテラルに明示的なエスケープシーケンスを使用する方が安全です。
開き長角括弧の直後に改行が続く場合、その改行は文字列に含まれません。以下に示す5つのリテラル文字列は、ASCIIを使用するシステム(例:'a'は97、改行は10、'1'は49としてコード化されている)において、同じ内容を表します。
a = 'alo\n123"'
a = "alo\n123\""
a = '\97lo\10\04923"'
a = [[alo
123"]]
a = [==[
alo
123"]==]数値定数は、小数部や10進数の指数部(eまたはEで示される)を含めることができます。Luaでは16進定数も受け付け、0xまたは0Xで始まります。16進定数には小数部および2進指数部(pまたはPで示される)も含められます。以下は有効な数値定数の例です。
3 3.0 3.1416 314.16e-2 0.31416E1
0xff 0x0.1E 0xA23p-4 0X1.921FB54442D18P+1コメントは、文字列外で--から始まります。--の直後に開き長角括弧がなければ、そのコメントは短いコメントとして行の終わりまで続きます。そうでなければ、それは長いコメントとなり、対応する閉じ長角括弧が現れるまで続きます。長いコメントはコードの一時的な無効化によく使われます。
3.2 – 変数
変数は値を格納する場所です。Luaには、グローバル変数、ローカル変数、およびテーブルフィールドの3種類の変数があります。
単一の名前は、グローバル変数やローカル変数(または関数の仮引数、特定のローカル変数)を表すことができます。
var ::= NameNameは§3.1で定義されている識別子を指します。変数名は特に指定しない限りグローバル変数とみなされます(§3.3.7を参照)。ローカル変数はレキシカルスコープを持ち、そのスコープ内で定義された関数から自由にアクセスできます(§3.5参照)。
変数に最初に値が代入される前の初期値はnilです。
テーブルのインデックス付けには角括弧を使用します。
var ::= prefixexp ‘[’ exp ‘]’テーブルフィールドへのアクセスの意味はメタテーブルを使って変更できます。インデックス付き変数t[i]へのアクセスは、gettable_event(t, i)の呼び出しと同等です(gettable_event関数はLuaで定義や呼び出しができませんが、説明のために用いています。§2.4を参照)。
構文var.Nameは単にvar["Name"]の構文糖(書き方の簡略化)です。
var ::= prefixexp ‘.’ Nameグローバル変数xへのアクセスは_ENV.xと同等です。チャンクのコンパイル方法により、_ENVはグローバル名にはなりません(§2.2を参照)。
3.3 – 文(Statements)
Luaは、PascalやCに似た一般的な文セットをサポートしています。このセットには、代入、制御構造、関数呼び出し、変数宣言が含まれます。
3.3.1 – ブロック(Blocks)
ブロックは一連の文のリストで、これらは順番に実行されます。
block ::= {stat}Luaには空の文があり、これにより文をセミコロンで区切ったり、ブロックをセミコロンで始めたり、セミコロンを2つ連続して書くことができます。
stat ::= ‘;’関数呼び出しや代入は開き括弧から始めることができます。このため、Luaの文法には曖昧さが生じる場合があります。次のコードを例にとります。
a = b + c
(print or io.write)('done')このコードは、次のように解釈できます。
a = b + c(print or io.write)('done')または
a = b + c; (print or io.write)('done')現在のパーサーは、開き括弧を関数呼び出しの引数の始まりと解釈するため、常に最初のように解釈されます。この曖昧さを避けるために、括弧で始まる文の前には常にセミコロンを置くのが良い習慣です。
;(print or io.write)('done')ブロックは、単一の文として明示的に区切ることもできます。
stat ::= do block end明示的なブロックは、変数宣言のスコープを制御するのに役立ちます。また、別のブロックの途中にreturn文を挿入する場合にも使用されます(§3.3.4を参照)。
3.3.2 – チャンク(Chunks)
Luaのコンパイル単位は「チャンク」と呼ばれます。文法的には、チャンクは単なるブロックです。
chunk ::= blockLuaはチャンクを、可変引数を持つ無名関数の本体として扱います(§3.4.10を参照)。そのため、チャンクはローカル変数を定義し、引数を受け取り、値を返すことができます。この無名関数は、外部ローカル変数である_ENVのスコープでコンパイルされます(§2.2を参照)。結果として生成される関数には、たとえ使用しなくても_ENVが唯一のアップバリューとして含まれます。
チャンクは、ファイル内またはホストプログラム内の文字列として保存できます。チャンクを実行するには、Luaがまず仮想マシン用の命令に事前コンパイルし、次にそのコンパイルされたコードを仮想マシン用のインタープリタで実行します。
チャンクはバイナリ形式に事前コンパイルすることもできます。詳細はluacプログラムを参照してください。ソース形式とコンパイル済み形式のプログラムは相互に交換可能であり、Luaはファイルの種類を自動的に検出し、それに応じた動作を行います。
3.3.3 – 代入(Assignment)
Luaでは複数の代入が可能です。そのため、代入の構文では、左側に変数リスト、右側に式のリストを定義します。両リストの要素はコンマで区切ります。
stat ::= varlist ‘=’ explist
varlist ::= var {‘,’ var}
explist ::= exp {‘,’ exp}式については§3.4で説明します。
代入の前に、値のリストは変数リストの長さに合わせて調整されます。必要な変数より多くの値がある場合、余剰の値は破棄されます。必要な値が不足している場合、リストは必要なだけnilで拡張されます。式リストが関数呼び出しで終わっている場合、その呼び出しによって返されるすべての値が値リストに含まれた後、リストの調整が行われます(関数呼び出しが括弧で囲まれている場合を除きます。詳細は§3.4を参照)。
代入文は、まずすべての式を評価し、その後で代入が実行されます。したがって、次のコードでは
i = 3
i, a[i] = i+1, 20a[3]が20に設定され、a[4]には影響がありません。これは、a[i]内のiが評価される(3に評価)前に4が代入されるためです。同様に、次のコードは
x, y = y, xxとyの値を入れ替え、次のコード
x, y, z = y, z, xはx、y、zの値を循環的に入れ替えます。
グローバル変数やテーブルフィールドへの代入の意味は、メタテーブルを使用して変更できます。インデックス付き変数t[i] = valへの代入は、settable_event(t, i, val)の呼び出しと同等です(settable_event関数はLuaで定義や呼び出しができませんが、説明のために使用しています。§2.4を参照)。
グローバル変数x = valへの代入は、_ENV.x = valの代入と同等です(§2.2を参照)。
3.3.4 – 制御構造
if、while、repeatの制御構造は、通常の意味とおなじみの構文を持っています。
stat ::= while exp do block end
stat ::= repeat block until exp
stat ::= if exp then block {elseif exp then block} [else block] endLuaにはfor文もあり、2種類の形式があります(§3.3.5を参照)。
制御構造の条件式は任意の値を返すことができます。falseとnilは「偽」と見なされます。それ以外のすべての値は「真」と見なされます(特に数値0や空文字列も「真」として扱われます)。
repeat–untilループでは、内部ブロックはuntilキーワードで終了せず、条件の後まで続きます。このため、条件はループブロック内で宣言されたローカル変数を参照できます。
goto文はプログラムの制御をラベルへ移します。構文上の理由から、Luaのラベルも文として扱われます。
stat ::= goto Name
stat ::= label
label ::= ‘::’ Name ‘::’ラベルは、そのブロック内で定義されている間は全体で可視です。ただし、同じ名前のラベルが定義されているネストされたブロックや、ネストされた関数内では可視ではありません。gotoはローカル変数のスコープに入らない限り、可視なラベルにジャンプできます。
ラベルや空の文は何の動作も行わないため、「無効文」と呼ばれます。
break文は、while、repeat、またはforループの実行を終了し、ループの後の次の文に進みます。
stat ::= breakbreakは最も内側のループを終了させます。
return文は、関数またはチャンク(見かけ上の関数)から値を返すために使用されます。関数は複数の値を返すことができるため、return文の構文は次のようになります。
stat ::= return [explist] [‘;’]return文はブロックの最後の文としてのみ書くことができます。ブロックの途中で値を返す必要がある場合は、do return endのように明示的な内部ブロックを使うことができます。これにより、returnがその(内部)ブロックの最後の文となります。
3.3.5 – For文
for文には数値形式と一般形式の2つの形式があります。
数値形式のforループは、制御変数が算術的な進行で進む間、ブロックを繰り返します。構文は次の通りです。
stat ::= for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block endブロックは、nameが最初のexpの値から始まり、第3のexpのステップごとに進み、第2のexpを超えるまで繰り返されます。より正確には、次のようなfor文
for v = e1, e2, e3 do block endは以下のコードと等価です。
do
local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
if not (var and limit and step) then error() end
while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
local v = var
block
var = var + step
end
end注意点は次の通りです。
- 制御式の3つの式は、ループの開始前に一度だけ評価されます。すべての式は数値である必要があります。
var、limit、stepは不可視の変数です。ここでの名前は説明用に使われています。- 第3の式(
step)が省略されると、ステップは1が使用されます。 breakを使ってforループを終了できます。- ループ変数
vはループ内でローカルです。forが終了するか中断された後はその値を使用できません。値が必要な場合は、ループを終了する前に他の変数に代入してください。
一般形式のfor文は、イテレータと呼ばれる関数で動作します。各反復で、イテレータ関数が呼び出され、新しい値が生成され、nilが返された時に停止します。一般形式のforループの構文は次の通りです。
stat ::= for namelist in explist do block end
namelist ::= Name {‘,’ Name}次のようなfor文
for var_1, ···, var_n in explist do block endは以下のコードと等価です。
do
local f, s, var = explist
while true do
local var_1, ···, var_n = f(s, var)
if var_1 == nil then break end
var = var_1
block
end
end注意点は次の通りです。
explistは一度だけ評価され、イテレータ関数、状態、および最初のイテレータ変数の初期値が結果として得られます。f、s、varは不可視の変数です。ここでの名前は説明用に使われています。breakを使ってforループを終了できます。- ループ変数
var_iはループ内でローカルです。forが終了する後はその値を使用できません。値が必要な場合は、ループを終了する前に他の変数に代入してください。
3.3.6 – 文としての関数呼び出し
副作用が生じる可能性を考慮して、関数呼び出しは文として実行することができます。
stat ::= functioncallこの場合、すべての戻り値は破棄されます。関数呼び出しについては§3.4.9で説明されています。
3.3.7 – ローカル変数の宣言
ローカル変数は、ブロック内の任意の場所で宣言できます。宣言には初期値の代入を含めることができます。
stat ::= local namelist [‘=’ explist]初期代入がある場合、その動作は複数代入と同じです(§3.3.3を参照)。ない場合、すべての変数はnilで初期化されます。
チャンクもブロックであるため(§3.3.2を参照)、ローカル変数は明示的なブロック外のチャンク内でも宣言できます。
ローカル変数の可視性ルールについては§3.5で説明されています。
3.4 – 式(Expressions)
Luaの基本的な式は次の通りです。
exp ::= prefixexp
exp ::= nil | false | true
exp ::= Number
exp ::= String
exp ::= functiondef
exp ::= tableconstructor
exp ::= ‘...’
exp ::= exp binop exp
exp ::= unop exp
prefixexp ::= var | functioncall | ‘(’ exp ‘)’数値とリテラル文字列は§3.1で説明され、変数は§3.2で、関数定義は§3.4.10で、関数呼び出しは§3.4.9で、テーブルコンストラクタは§3.4.8で説明されています。可変引数式(...で示される)は、可変引数を持つ関数内で直接使用する場合にのみ有効です(§3.4.10を参照)。
二項演算子には、算術演算子(§3.4.1参照)、関係演算子(§3.4.3参照)、論理演算子(§3.4.4参照)、および連結演算子(§3.4.5参照)が含まれます。単項演算子には、単項マイナス(§3.4.1参照)、単項否定(not、§3.4.4参照)、および単項長さ演算子(#、§3.4.6参照)が含まれます。
関数呼び出しと可変引数式は、複数の値を返す場合があります。関数呼び出しが文として使用される場合(§3.3.6を参照)、戻り値のリストは0要素に調整され、すべての戻り値が破棄されます。式が式リストの最後の要素(または唯一の要素)として使用される場合、調整は行われません(式が括弧で囲まれている場合を除く)。それ以外のすべての状況で、Luaは戻り値のリストを1つの要素に調整し、最初の値以外を破棄するか、値がない場合はnilを追加します。
以下にいくつかの例を示します。
f() -- 0個の結果に調整
g(f(), x) -- f()は1個の結果に調整される
g(x, f()) -- gはxとf()のすべての結果を取得
a, b, c = f(), x -- f()は1個の結果に調整され、cにはnilが代入される
a, b = ... -- aには最初の可変引数、bには2番目が入る(可変引数がなければaやbにはnilが入る)
a, b, c = x, f() -- f()は2個の結果に調整される
a, b, c = f() -- f()は3個の結果に調整される
return f() -- f()のすべての結果を返す
return ... -- 受け取った可変引数をすべて返す
return x, y, f() -- x, yとf()のすべての結果を返す
{f()} -- f()のすべての結果を含むリストを作成
{...} -- すべての可変引数を含むリストを作成
{f(), nil} -- f()は1個の結果に調整される括弧で囲まれた任意の式は、常に1つの値のみを返します。したがって、(f(x, y, z))はfが複数の値を返す場合でも常に単一の値です。((f(x, y, z))の値は、fが返す最初の値、またはfが何も返さない場合はnilです。)
3.4.1 – 算術演算子
Luaは一般的な算術演算子をサポートしています。二項演算子の+(加算)、-(減算)、*(乗算)、/(除算)、%(剰余)、^(べき乗)と、単項演算子の-(数学的な否定)です。オペランドが数値または数値に変換できる文字列(§3.4.2を参照)であれば、すべての演算子は通常の意味で動作します。べき乗は任意の指数に対応し、例えばx^(-0.5)はxの平方根の逆数を計算します。剰余演算は次のように定義されます。
a % b == a - math.floor(a/b)*bこれは、商をマイナス無限大に向かって丸めた除算の余りに相当します。
3.4.2 – 型変換
Luaは、実行時に文字列と数値の間の自動変換を提供します。文字列に対して算術演算が適用される場合、その文字列はLuaの字句解析器の規則に従って数値に変換されます(文字列には前後のスペースや符号が含まれていても構いません)。逆に、文字列が必要な箇所で数値が使われた場合、数値は適切な形式で文字列に変換されます。数値の文字列への変換を完全に制御するには、文字列ライブラリのformat関数を使用してください(string.formatを参照)。
3.4.3 – 関係演算子
Luaの関係演算子は以下の通りです。
== ~= < > <= >=これらの演算子は常にfalseまたはtrueを返します。
等価演算子==は、まずオペランドの型を比較します。型が異なる場合、結果はfalseになります。型が同じであれば、オペランドの値を比較します。数値と文字列は通常通り比較され、テーブル、ユーザデータ、スレッドは参照によって比較されます。つまり、2つのオブジェクトが同じオブジェクトである場合にのみ等しいと見なされます。新しいオブジェクト(テーブル、ユーザデータ、スレッド)を作成するたびに、それは既存のオブジェクトとは異なります。同じ参照を持つクロージャは常に等しいと見なされ、異なる動作や定義を持つクロージャは常に異なると見なされます。
テーブルやユーザデータの比較方法は、"eq"メタメソッドを使用して変更できます(§2.4を参照)。
§3.4.2の変換ルールは等価比較には適用されません。したがって、"0" == 0はfalseを返し、t[0]とt["0"]はテーブル内の異なるエントリを示します。
演算子~=は等価演算子==の否定です。
順序演算子は次のように動作します。両方の引数が数値であれば、数値として比較されます。両方の引数が文字列であれば、現在のロケールに従って値を比較します。それ以外の場合、Luaは"lt"または"le"メタメソッドを呼び出そうとします(§2.4を参照)。比較a > bはb < aに、a >= bはb <= aに変換されます。
3.4.4 – 論理演算子
Luaの論理演算子にはand、or、notがあります。制御構造と同様(§3.3.4参照)、論理演算子はfalseとnilを「偽」とし、それ以外を「真」と見なします。
否定演算子notは常にfalseまたはtrueを返します。論理積演算子andは、最初の引数がfalseまたはnilの場合、その引数を返し、それ以外の場合は2番目の引数を返します。論理和演算子orは、最初の引数がnilおよびfalse以外であればその引数を返し、それ以外の場合は2番目の引数を返します。andとorは短絡評価を行い、2番目のオペランドは必要な場合にのみ評価されます。いくつかの例を以下に示します。
10 or 20 --> 10
10 or error() --> 10
nil or "a" --> "a"
nil and 10 --> nil
false and error() --> false
false and nil --> false
false or nil --> nil
10 and 20 --> 20(このマニュアルでは、-->は前の式の結果を示しています。)
3.4.5 – 連結
Luaの文字列連結演算子は2つのドット(..)で示されます。両方のオペランドが文字列または数値であれば、§3.4.2で説明されている規則に従って文字列に変換されます。それ以外の場合、__concatメタメソッドが呼び出されます(§2.4を参照)。
3.4.6 – 長さ演算子
長さ演算子は単項の接頭辞演算子#で表されます。文字列の長さは、そのバイト数です(つまり、各文字が1バイトの場合の通常の文字列の長さの意味になります)。
文字列以外の値に対して長さ演算子の動作を変更するには、__lenメタメソッドを使用できます(§2.4を参照)。
__lenメタメソッドが指定されていない場合、テーブルtの長さは、テーブルが「シーケンス」(正の数値キーの集合が{1..n}と一致する非負整数nが存在する)である場合にのみ定義されます。この場合、nがそのテーブルの長さです。例えば、以下のようなテーブル
{10, 20, nil, 40}はキー4を持ちますが、キー3がないためシーケンスではありません(つまり、このテーブルの正の数値キーの集合が{1..n}と一致するようなnは存在しません)。ただし、数値でないキーはテーブルがシーケンスであるかどうかには影響を与えません。
3.4.7 – 優先順位
Luaにおける演算子の優先順位は次の表に示されており、下から上に向かって優先順位が高くなります。
or
and
< > <= >= ~= ==
..
+ -
* / %
not # - (単項)
^通常、式の優先順位を変更するには括弧を使用します。連結演算子(..)およびべき乗演算子(^)は右結合です。それ以外の二項演算子は左結合です。
3.4.8 – テーブルコンストラクタ
テーブルコンストラクタはテーブルを作成する式です。コンストラクタが評価されるたびに新しいテーブルが作成されます。コンストラクタを使用して空のテーブルを作成したり、いくつかのフィールドを初期化したテーブルを作成したりできます。コンストラクタの一般的な構文は次の通りです。
tableconstructor ::= ‘{’ [fieldlist] ‘}’
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
fieldsep ::= ‘,’ | ‘;’[exp1] = exp2形式の各フィールドは、新しいテーブルにキーexp1と値exp2を持つエントリを追加します。name = exp形式のフィールドは["name"] = expと等価です。最後に、exp形式のフィールドは、iが1から始まる連続する数値インデックスで[i] = expと等価です。その他の形式のフィールドはこのカウントに影響しません。例えば、
a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }は以下のコードと等価です。
do
local t = {}
t[f(1)] = g
t[1] = "x" -- 1番目のexp
t[2] = "y" -- 2番目のexp
t.x = 1 -- t["x"] = 1
t[3] = f(x) -- 3番目のexp
t[30] = 23
t[4] = 45 -- 4番目のexp
a = t
endリストの最後のフィールドがexp形式で、式が関数呼び出しや可変引数式である場合、その式が返すすべての値がリストに連続して追加されます(§3.4.9を参照)。
フィールドリストには、機械生成コードの便宜のため、末尾の区切り記号を省略可能にすることができます。
3.4.9 – 関数呼び出し
Luaにおける関数呼び出しの構文は次の通りです。
functioncall ::= prefixexp args関数呼び出しでは、まずprefixexpとargsが評価されます。prefixexpの値が関数型であれば、その関数が指定された引数で呼び出されます。そうでない場合は、prefixexpの"call"メタメソッドが呼び出され、最初のパラメータとしてprefixexpの値が渡され、続いて元の呼び出し引数が渡されます(§2.4を参照)。
次の形式
functioncall ::= prefixexp ‘:’ Name argsは「メソッド」を呼び出すために使用されます。v:name(args)という呼び出しはv.name(v, args)の構文糖にすぎませんが、vは一度だけ評価されます。
引数の構文は以下の通りです。
args ::= ‘(’ [explist] ‘)’
args ::= tableconstructor
args ::= Stringすべての引数式は呼び出し前に評価されます。f{fields}形式の呼び出しはf({fields})の構文糖であり、引数リストが1つの新しいテーブルになります。同様に、f'string'(またはf"string"やf[[string]])形式の呼び出しはf('string')の構文糖で、引数リストは1つのリテラル文字列になります。
return functioncall形式の呼び出しは「末尾呼び出し」と呼ばれます。Luaは適切な末尾呼び出し(または適切な末尾再帰)を実装しています。末尾呼び出しでは、呼び出される関数が呼び出し元の関数のスタックエントリを再利用するため、プログラムで実行できる末尾呼び出しのネスト数に制限はありません。ただし、末尾呼び出しは呼び出し元のデバッグ情報を消去します。末尾呼び出しは特定の構文でのみ行われ、returnが1つの関数呼び出しだけを引数として持つ場合に、呼び出し元の関数が呼び出される関数の戻り値をそのまま返します。したがって、以下の例は末尾呼び出しにはなりません。
return (f(x)) -- 結果は1つに調整される
return 2 * f(x)
return x, f(x) -- 追加の結果がある
f(x); return -- 結果が破棄される
return x or f(x) -- 結果は1つに調整される3.4.10 – 関数定義
関数定義の構文は次の通りです。
functiondef ::= function funcbody
funcbody ::= ‘(’ [parlist] ‘)’ block end関数定義を簡略化する構文糖は以下の通りです。
stat ::= function funcname funcbody
stat ::= local function Name funcbody
funcname ::= Name {‘.’ Name} [‘:’ Name]次の文
function f () body endは、以下のように変換されます。
f = function () body endまた、次の文
function t.a.b.c.f () body endは、以下のように変換されます。
t.a.b.c.f = function () body endさらに、次の文
local function f () body endは以下に変換されますが、
local f; f = function () body end次のようには変換されません。
local f = function () body end(これは、関数本体がfへの参照を含む場合にのみ違いが生じます。)
関数定義は実行可能な式で、その値はfunction型を持ちます。Luaがチャンクを事前コンパイルすると、その中のすべての関数本体も事前コンパイルされます。そして、Luaが関数定義を実行するたびに、関数がインスタンス化(またはクローズ)されます。この関数インスタンス(クロージャ)が式の最終的な値となります。
パラメータは、引数の値で初期化されるローカル変数として機能します。
parlist ::= namelist [‘,’ ‘...’] | ‘...’関数が呼び出されると、引数リストはパラメータリストの長さに合わせて調整されます。ただし、パラメータリストの末尾に3つのドット(...)がある可変引数関数の場合、引数リストの調整は行われません。その代わりに、すべての追加の引数が可変引数式(...で表されます)を通じて関数に渡されます。この式の値は、追加の引数すべてを含むリストとなり、複数の戻り値を持つ関数と似ています。可変引数式が他の式内や式リストの途中で使用される場合、その戻り値リストは1つの要素に調整されます。式リストの最後の要素として使用される場合は、調整は行われません(ただし、その最後の式が括弧で囲まれている場合を除きます)。
例として、以下の定義を考えます。
function f(a, b) end
function g(a, b, ...) end
function r() return 1,2,3 endこのとき、引数とパラメータおよび可変引数式への対応は以下のようになります。
CALL PARAMETERS
f(3) a=3, b=nil
f(3, 4) a=3, b=4
f(3, 4, 5) a=3, b=4
f(r(), 10) a=1, b=10
f(r()) a=1, b=2
g(3) a=3, b=nil, ... --> (なし)
g(3, 4) a=3, b=4, ... --> (なし)
g(3, 4, 5, 8) a=3, b=4, ... --> 5 8
g(5, r()) a=5, b=1, ... --> 2 3戻り値はreturn文を使用して返されます(§3.3.4参照)。return文に遭遇しないまま関数の終わりに達すると、関数は戻り値なしで終了します。
システム依存で、関数が返すことのできる値の数には制限があります。この制限は1000以上であることが保証されています。
コロン構文はメソッド(暗黙的に追加のパラメータselfを持つ関数)を定義するために使用されます。したがって、次の文
function t.a.b.c:f (params) body endは、以下の構文糖として扱われます。
t.a.b.c.f = function (self, params) body end3.5 – 可視性ルール
Luaは字句スコープを持つ言語です。ローカル変数のスコープは、その宣言の後の最初の文から始まり、その宣言を含む最も内側のブロックの最後の有効な(空でない)文まで続きます。次の例を見てみましょう。
x = 10 -- グローバル変数
do -- 新しいブロック
local x = x -- 新しい'x'、値は10
print(x) --> 10
x = x+1
do -- 別のブロック
local x = x+1 -- 別の'x'
print(x) --> 12
end
print(x) --> 11
end
print(x) --> 10 (グローバルの'x')この例では、local x = xのような宣言の場合、宣言されている新しいxはまだスコープ内にないため、2番目のxは外側の変数を参照しています。
字句スコープの規則により、ローカル変数はそのスコープ内で定義された関数から自由にアクセスできます。内部関数で使用されるローカル変数は、内部関数内では「アップバリュー」または「外部ローカル変数」と呼ばれます。
また、ローカル文が実行されるたびに新しいローカル変数が定義される点にも注意が必要です。以下の例を見てみましょう。
a = {}
local x = 20
for i=1,10 do
local y = 0
a[i] = function () y=y+1; return x+y end
endこのループは10個のクロージャ(つまり無名関数の10個のインスタンス)を作成します。これらのクロージャはそれぞれ異なるy変数を使用し、すべてが同じx変数を共有しています。
4 – アプリケーションプログラムインターフェース(API)
このセクションでは、LuaのC API、つまりLuaとの通信に使用できるホストプログラム向けのC関数セットについて説明します。すべてのAPI関数および関連する型や定数は、ヘッダーファイルlua.hに宣言されています。
「関数」という用語を使用していますが、API内の機能はマクロとして提供される場合もあります。特に明記されていない限り、これらのマクロは、引数を一度だけ使用します(最初の引数は常にLuaの状態を指します)。したがって、隠れた副作用を生成しません。
多くのCライブラリと同様に、Lua API関数は引数の有効性や整合性をチェックしません。ただし、LuaをLUA_USE_APICHECKマクロを定義してコンパイルすることで、この動作を変更することができます。
4.1 – スタック
Luaは、Cとの間で値をやり取りするために仮想スタックを使用します。このスタックの各要素は、Luaの値(nil、数値、文字列など)を表します。
LuaがCを呼び出すたびに、呼び出された関数は新しいスタックを受け取ります。このスタックは、以前のスタックや依然としてアクティブなC関数のスタックとは独立しています。このスタックには最初にC関数への引数が含まれており、C関数が結果をプッシュして呼び出し元に返す場所でもあります(lua_CFunctionを参照)。
便宜上、APIの多くのクエリ操作では厳密なスタック規律に従う必要はありません。代わりに、スタック内の任意の要素にインデックスを使って参照できます。正のインデックスは絶対的なスタック位置を表し(1から始まります)、負のインデックスはスタックのトップからの相対的なオフセットを表します。具体的には、スタックにn個の要素がある場合、インデックス1は最初の要素(最初にプッシュされた要素)を、インデックスnは最後の要素を表します。また、インデックス-1も最後の要素(つまりトップの要素)を、インデックス-nは最初の要素を表します。
4.2 – スタックサイズ
Lua APIと対話する際には、一貫性を保つ責任がユーザーにあります。特に、スタックのオーバーフローを制御する責任があります。新しい要素をプッシュする際には、lua_checkstack関数を使ってスタックに追加のスロットがあることを確認できます。
LuaがCを呼び出すたびに、スタックには少なくともLUA_MINSTACKの追加スロットが確保されます。LUA_MINSTACKは20として定義されており、通常、コードにスタックへの要素のプッシュを伴うループがない限り、スタックのスペースについて心配する必要はありません。
結果の数が固定されていない状態でLua関数を呼び出すとき(lua_callを参照)、Luaはすべての結果に対してスタックサイズが十分であることを保証しますが、追加のスペースは保証しません。したがって、そのような呼び出し後にスタックに新しい要素をプッシュする前には、lua_checkstackを使用する必要があります。
4.3 – 有効なインデックスと許容インデックス
APIでスタックインデックスを受け取る関数は、有効なインデックスまたは許容インデックスのみで動作します。
有効なインデックスとは、スタック内の実際の位置を指すインデックスのことで、その位置は1からスタックトップまでの間にあります(1 ≤ abs(index) ≤ top)。通常、インデックスで値を変更できる関数は有効なインデックスを要求します。
特に記載がない限り、有効なインデックスを受け入れる関数は擬似インデックスも受け入れます。擬似インデックスは、スタックには存在しないもののCコードからアクセス可能なLuaの値を表します。擬似インデックスは、レジストリやC関数のアップバリューにアクセスするために使用されます(§4.4参照)。
特定のスタック位置を必要とせず、スタック内の値のみを必要とする関数(クエリ関数など)は、許容インデックスで呼び出すことができます。許容インデックスは、有効なインデックス(擬似インデックスを含む)であるほか、スタックトップの後のスタックサイズ内の任意の正のインデックスであることもできます(スタックサイズまでのインデックスです)。ただし、0は許容インデックスにはなりません。特に記載がない限り、APIの関数は許容インデックスで動作します。
許容インデックスは、スタックトップとの余分なチェックを省略するために役立ちます。たとえば、C関数は第3引数を取得する際、3が有効なインデックスかを事前に確認する必要なく、直接アクセスできます。
許容インデックスで呼び出せる関数において、有効でないインデックスは仮想タイプLUA_TNONEの値が入っているかのように扱われ、これはnil値のように振る舞います。
4.4 – Cクロージャ
C関数が作成される際に、いくつかの値を関連付けることができ、これによりCクロージャが作成されます(lua_pushcclosure参照)。これらの値はアップバリューと呼ばれ、関数が呼び出されるたびにアクセス可能です。
C関数が呼び出されるたびに、そのアップバリューは特定の擬似インデックスに配置されます。これらの擬似インデックスはマクロlua_upvalueindexによって生成されます。関数に関連付けられた最初の値はlua_upvalueindex(1)の位置にあり、以下同様です。現在の関数のアップバリューの数を超えるlua_upvalueindex(n)へのアクセス(ただし256以下)は、許容されるが無効なインデックスを生成します。
4.5 – レジストリ
Luaは「レジストリ」と呼ばれる事前定義されたテーブルを提供しており、Cコードが必要なLuaの値を格納するために使用できます。レジストリテーブルは常に擬似インデックスLUA_REGISTRYINDEXに位置し、これは有効なインデックスです。任意のCライブラリがこのテーブルにデータを格納できますが、他のライブラリとの衝突を避けるため、異なるキーを選択することが推奨されます。通常、キーとしてはライブラリ名を含む文字列、Cオブジェクトのアドレスを持つライトユーザーデータ、またはコード内で生成した任意のLuaオブジェクトを使用するのが良いでしょう。グローバル名と同様、アンダースコアと大文字で始まる文字列キー(例:_VERSION)はLuaで予約されています。
レジストリの整数キーは、補助ライブラリで実装されている参照機構やいくつかの事前定義された値に使用されています。したがって、整数キーは他の目的には使用しないでください。
新しいLua状態を作成すると、そのレジストリにはいくつかの事前定義された値が含まれます。これらの事前定義値は、lua.hに定数として定義された整数キーでインデックスされています。定義されている定数は以下の通りです。
- LUA_RIDX_MAINTHREAD: このインデックスには、状態のメインスレッドがレジストリに格納されています(メインスレッドは状態とともに作成されるスレッドです)。
- LUA_RIDX_GLOBALS: このインデックスにはグローバル環境がレジストリに格納されています。
4.6 – Cでのエラーハンドリング
Lua内部では、エラー処理にCのlongjmp機能を使用しています(LuaをC++としてコンパイルする場合は、例外処理を使用することもできます。詳細はソースコード内のLUAI_THROWを参照してください)。Luaがエラーに遭遇した場合(例えばメモリ割り当てエラー、型エラー、構文エラー、実行時エラー)、エラーを発生させてlong jumpを行います。保護環境ではsetjmpを使用して復旧ポイントを設定し、エラーが発生すると最新のアクティブな復旧ポイントにジャンプします。
保護環境の外でエラーが発生した場合、Luaはパニック関数(lua_atpanic参照)を呼び出してからabortを実行し、ホストアプリケーションを終了します。パニック関数は、終了せずに(例えば自分で設定した復旧ポイントにlong jumpするなどして)この終了を回避できます。
パニック関数は、メッセージハンドラとして実行され(§2.3参照)、エラーメッセージがスタックのトップにあります。ただし、スタックのスペースに関しては保証がないため、スタックに何かをプッシュする前に空きスペースを確認する必要があります(§4.2参照)。
API内のほとんどの関数は、メモリ割り当てエラーなどの理由でエラーをスローする可能性があります。各関数のドキュメントには、エラーをスローする可能性があるかどうかが記載されています。
C関数内でエラーをスローするには、lua_errorを呼び出します。
4.7 – Cでのコルーチンのyield処理
Lua内部では、コルーチンをyieldするためにCのlongjmp機能を使用します。このため、関数fooがAPI関数を呼び出し、そのAPI関数がyield(直接または他のyieldを呼び出す関数を介して)する場合、longjmpによりCスタックからそのフレームが削除されるため、Luaはfooに戻れなくなります。
この問題を回避するため、LuaはAPI呼び出しをまたいでyieldしようとする際にエラーを発生させます。ただし、例外としてlua_yieldk、lua_callk、およびlua_pcallkの3つの関数はこのエラーをスローしません。これらの関数はすべて、yield後の実行を続けるための継続関数(kという名前のパラメータとして)を受け取ります。
継続を説明するために、いくつかの用語を定義する必要があります。Luaから呼び出されるC関数を「元の関数」と呼びます。この元の関数は、C API内の3つの関数のいずれか(「被呼び出し関数」と呼びます)を呼び出し、現在のスレッドをyieldします(被呼び出し関数がlua_yieldkである場合、または被呼び出し関数がlua_callkまたはlua_pcallkで、それらによって呼び出された関数がyieldした場合にこの状況が発生します)。
被呼び出し関数の実行中にスレッドがyieldするとします。スレッドが再開された後、最終的に被呼び出し関数の実行が終了します。しかし、yieldによってCスタックのフレームが破棄されているため、被呼び出し関数は元の関数に戻ることができません。代わりに、Luaは被呼び出し関数に引数として渡された継続関数を呼び出します。名前が示す通り、継続関数は元の関数のタスクを継続すべきものです。
Luaは継続関数を元の関数として扱います。継続関数は元の関数と同じLuaスタックを受け取り、被呼び出し関数が戻った場合と同じ状態になります(例えば、lua_callkの後では、関数とその引数がスタックから取り除かれ、呼び出しの結果に置き換えられます)。また、同じアップバリューも持ちます。Luaは継続関数が返すものを元の関数の返り値として扱います。
元の関数とその継続関数のLuaの状態の唯一の違いは、lua_getctxを呼び出した際の結果です。
4.8 – 関数と型
ここでは、C APIのすべての関数と型をアルファベット順にリストします。各関数には次のような指標が付いています:[-o, +p, x]
- 最初の項目
oは、関数がスタックから取り出す(ポップする)要素の数です。 - 2番目の項目
pは、関数がスタックにプッシュする要素の数です。(すべての関数は、引数をポップした後で結果をプッシュします。) x|yのような形式の項目は、状況に応じてxまたはyの要素をプッシュ(またはポップ)することを意味し、?は引数だけではポップ/プッシュする要素数を特定できないことを示します(例えば、スタックの内容によって変わる場合など)。- 3番目の項目
xは、関数がエラーをスローする可能性を示します。-はエラーを決してスローしないこと、eはエラーをスローする可能性があること、vは意図的にエラーをスローする可能性があることを意味します。
lua_absindex
[-0, +0, –]
int lua_absindex (lua_State *L, int idx);受け入れ可能なインデックスidxを絶対インデックス(スタックトップに依存しないもの)に変換します。
lua_Alloc
typedef void * (*lua_Alloc) (void *ud,
void *ptr,
size_t osize,
size_t nsize);Lua状態が使用するメモリ割り当て関数の型です。アロケータ関数はreallocと似た機能を提供する必要がありますが、完全に同じである必要はありません。この関数の引数は以下の通りです:
ud:lua_newstateに渡される不透明なポインタptr: 割り当て/再割り当て/解放されるブロックを指すポインタosize: ブロックの元のサイズ、または割り当てるものに関するコードnsize: ブロックの新しいサイズ
ptrがNULLでない場合、osizeはptrが指すブロックのサイズ(割り当てまたは再割り当て時に指定されたサイズ)です。
ptrがNULLの場合、osizeはLuaが割り当てようとしているオブジェクトの種類を表します。このとき、osizeはLUA_TSTRING、LUA_TTABLE、LUA_TFUNCTION、LUA_TUSERDATA、またはLUA_TTHREADのいずれかです。osizeがこれら以外の値の場合、Luaは他の用途のためにメモリを割り当てています。
Luaはアロケータ関数に以下の動作を期待します:
nsizeが0の場合、アロケータはfreeのように動作し、NULLを返すべきです。nsizeが0でない場合、アロケータはreallocのように動作し、要求を満たせない場合のみNULLを返します。Luaは、osize >= nsizeのとき、アロケータが失敗しないと想定しています。
以下は、補助ライブラリ内でluaL_newstateに使用されるシンプルなアロケータ関数の実装例です。
static void *l_alloc (void *ud, void *ptr, size_t osize,
size_t nsize) {
(void)ud; (void)osize; /* 使用しない */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}標準Cは、free(NULL)が何の影響も及ぼさないことと、realloc(NULL, size)がmalloc(size)と同等であることを保証しています。このコードは、reallocがブロックを縮小する際に失敗しないことを前提としています(標準Cはこの動作を保証していませんが、安全な前提と考えられています)。
lua_arith
[-(2|1), +1, e]
void lua_arith (lua_State *L, int op);スタックトップの2つの値(または、単項の否定の場合は1つの値)に対して算術演算を行います。スタックトップの値が2番目のオペランドとして扱われ、これらの値をポップして、演算結果をプッシュします。この関数は対応するLua演算子のセマンティクスに従います(つまり、メタメソッドを呼び出す場合もあります)。
opの値は以下の定数のいずれかである必要があります:
LUA_OPADD: 加算(+)LUA_OPSUB: 減算(-)LUA_OPMUL: 乗算(*)LUA_OPDIV: 除算(/)LUA_OPMOD: 剰余(%)LUA_OPPOW: べき乗(^)LUA_OPUNM: 数学的な否定(単項の-)
lua_atpanic
[-0, +0, –]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);新しいパニック関数を設定し、以前のパニック関数を返します(§4.6参照)。
lua_call
[-(nargs+1), +nresults, e]
void lua_call (lua_State *L, int nargs, int nresults);関数を呼び出します。
関数を呼び出すには、次のプロトコルに従う必要があります。まず、呼び出す関数をスタックにプッシュし、次に引数を順番にプッシュします。最初の引数が最初にプッシュされます。最後にlua_callを呼び出します。nargsはスタックにプッシュされた引数の数です。呼び出された関数の引数と関数自体はスタックからポップされ、関数の戻り値がスタックにプッシュされます。戻り値の数はnresultsに調整され、nresultsがLUA_MULTRETの場合、すべての戻り値がプッシュされます。Luaは戻り値がスタックに収まるように調整します。戻り値は順番にスタックにプッシュされるため、呼び出し後、最後の結果がスタックトップにあります。
呼び出された関数内でエラーが発生すると、そのエラーは上位に伝播されます(longjmpで処理)。
次の例は、ホストプログラムが以下のLuaコードに相当する操作を行う方法を示します:
a = f("how", t.x, 14)Cでの実装例:
lua_getglobal(L, "f"); /* 呼び出す関数 */
lua_pushstring(L, "how"); /* 1番目の引数 */
lua_getglobal(L, "t"); /* インデックスされるテーブル */
lua_getfield(L, -1, "x"); /* t.xの結果(2番目の引数)をプッシュ */
lua_remove(L, -2); /* スタックから't'を削除 */
lua_pushinteger(L, 14); /* 3番目の引数 */
lua_call(L, 3, 1); /* 'f'を3つの引数で呼び出し、1つの結果を取得 */
lua_setglobal(L, "a"); /* グローバル変数'a'を設定 */上記のコードは「バランスが取れている」状態で、終了時にスタックは元の構成に戻ります。これは良いプログラミングの習慣とされています。
lua_callk
[-(nargs + 1), +nresults, e]
void lua_callk (lua_State *L, int nargs, int nresults, int ctx,
lua_CFunction k);この関数はlua_callと同様に動作しますが、呼び出された関数がyieldできるようにします(§4.7参照)。
lua_CFunction
typedef int (*lua_CFunction) (lua_State *L);C関数の型。
Luaと適切に通信するために、C関数はパラメータと結果の渡し方を定義する次のプロトコルを使用する必要があります。C関数はスタック上に直接順序でLuaから引数を受け取ります(最初の引数が最初にプッシュされます)。関数が開始されると、lua_gettop(L)が受け取った引数の数を返します。最初の引数(存在する場合)はインデックス1にあり、最後の引数はlua_gettop(L)にあります。Luaに戻り値を返すには、C関数は直接順序でスタックにプッシュするだけです(最初の結果が最初にプッシュされます)。結果以外のスタック内の他の値はLuaによって適切に破棄されます。Lua関数と同様に、Luaから呼び出されたC関数も複数の結果を返すことができます。
以下の例は、数値引数の可変個を受け取り、その平均と合計を返す関数です。
static int foo (lua_State *L) {
int n = lua_gettop(L); /* 引数の数 */
lua_Number sum = 0;
int i;
for (i = 1; i <= n; i++) {
if (!lua_isnumber(L, i)) {
lua_pushstring(L, "incorrect argument");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* 1番目の結果 */
lua_pushnumber(L, sum); /* 2番目の結果 */
return 2; /* 結果の数 */
}lua_checkstack
[-0, +0, –]
int lua_checkstack (lua_State *L, int extra);スタックに最低でもextra個の空きスロットがあることを保証します。スタックが最大サイズ(通常は数千の要素)を超えるか、新しいスタックサイズのメモリを確保できない場合、この関数は要求を満たせずにfalseを返します。この関数はスタックを縮小することはありません。スタックがすでに新しいサイズよりも大きい場合、変更されません。
lua_close
[-0, +0, –]
void lua_close (lua_State *L);指定されたLua状態のすべてのオブジェクトを破棄し(対応するガベージコレクションメタメソッドがある場合は呼び出します)、この状態で使用されたすべての動的メモリを解放します。いくつかのプラットフォームでは、ホストプログラムが終了するときにすべてのリソースが自然に解放されるため、この関数を呼び出す必要はありません。一方で、デーモンやWebサーバーのように長期間動作するプログラムで複数の状態を作成する場合は、不要になった状態をすぐに閉じることが必要です。
lua_compare
[-0, +0, e]
int lua_compare (lua_State *L, int index1, int index2, int op);2つのLua値を比較します。index1の位置にある値がindex2の位置にある値と比較してopを満たす場合、1を返します。そうでなければ0を返します。また、どちらかのインデックスが無効な場合も0を返します。比較は対応するLua演算子のセマンティクスに従います(つまり、メタメソッドを呼び出す場合もあります)。
opの値は次の定数のいずれかでなければなりません:
LUA_OPEQ: 等価比較(==)LUA_OPLT: 小なり比較(<)LUA_OPLE: 以下比較(<=)
lua_concat
[-n, +1, e]
void lua_concat (lua_State *L, int n);スタックトップのn個の値を連結し、それらをポップして結果をトップに残します。nが1の場合、結果はスタック上の単一の値です(つまり、関数は何もしません)。nが0の場合、結果は空文字列になります。連結は通常のLuaのセマンティクスに従います(§3.4.5参照)。
lua_copy
[-0, +0, –]
void lua_copy (lua_State *L, int fromidx, int toidx);fromidxの位置にある要素を有効なインデックスtoidxに移動し、他の要素をシフトせずにその位置の値を置き換えます。
lua_createtable
[-0, +1, e]
void lua_createtable (lua_State *L, int narr, int nrec);新しい空のテーブルを作成し、スタックにプッシュします。パラメータnarrはテーブルがシーケンスとして持つ要素数の予想、nrecはその他の要素数の予想です。Luaはこれらのヒントを使って新しいテーブルのメモリを事前に割り当てる場合があります。事前割り当ては、テーブルの要素数が事前にわかっている場合にパフォーマンス上の利点があります。それ以外の場合、lua_newtable関数を使用できます。
lua_dump
[-0, +0, e]
int lua_dump (lua_State *L, lua_Writer writer, void *data);関数をバイナリチャンクとしてダンプします。スタックのトップにあるLua関数を受け取り、それをバイナリチャンクとして出力します。このチャンクを再度ロードすると、ダンプされた関数と同等の関数が得られます。チャンクの各部分が生成されると、lua_dumpは指定されたdataを使用して書き込み関数writer(lua_Writer参照)を呼び出します。
返される値は、writerの最後の呼び出しで返されたエラーコードです。0はエラーがないことを意味します。
この関数は、Lua関数をスタックからポップしません。
lua_error
[-1, +0, v]
int lua_error (lua_State *L);Luaエラーを生成します。エラーメッセージ(任意のLua型の値で構いません)はスタックトップにある必要があります。この関数はlong jumpを行うため、戻ることはありません(luaL_error参照)。
lua_gc
[-0, +0, e]
int lua_gc (lua_State *L, int what, int data);ガベージコレクタを制御します。
whatの値に応じて、この関数は以下のタスクを実行します:
LUA_GCSTOP: ガベージコレクタを停止します。LUA_GCRESTART: ガベージコレクタを再開します。LUA_GCCOLLECT: 完全なガベージコレクションサイクルを実行します。LUA_GCCOUNT: Luaが使用中のメモリの現在量(Kバイト単位)を返します。LUA_GCCOUNTB: Luaが使用中のメモリ量(バイト単位)を1024で割った余りを返します。LUA_GCSTEP: ガベージコレクションの増分ステップを実行します。ステップ「サイズ」はdataで制御されます(大きい値ほど多くのステップが実行されます)。この値は実験的に調整する必要があります。サイクルが完了した場合、関数は1を返します。LUA_GCSETPAUSE: コレクタの停止値を新しいdata値に設定し、以前の値を返します(§2.5参照)。LUA_GCSETSTEPMUL: コレクタのステップ乗数を新しいdata値に設定し、以前の値を返します(§2.5参照)。LUA_GCISRUNNING: コレクタが動作中(停止していない)かを示すブール値を返します。LUA_GCGEN: コレクタを世代別モードに切り替えます(§2.5参照)。LUA_GCINC: コレクタを増分モードに切り替えます。これはデフォルトのモードです。
これらのオプションの詳細についてはcollectgarbageを参照してください。
lua_getallocf
[-0, +0, –]
lua_Alloc lua_getallocf (lua_State *L, void **ud);指定された状態のメモリ割り当て関数を返します。udがNULLでない場合、Luaは*udにlua_newstateに渡された不透明なポインタを格納します。
lua_getctx
[-0, +0, –]
int lua_getctx (lua_State *L, int *ctx);継続関数(§4.7参照)がスレッドの状態とコンテキスト情報を取得するために呼び出されます。
元の関数内で呼び出されると、lua_getctxは常にLUA_OKを返し、引数ctxの値を変更しません。継続関数内で呼び出されると、lua_getctxはLUA_YIELDを返し、ctxにコンテキスト情報(継続関数と共に被呼び出し関数に渡されたctx引数の値)を設定します。
被呼び出し関数がlua_pcallkの場合、Luaは呼び出し中のエラー処理にも継続関数を呼び出すことがあります。つまり、lua_pcallkによって呼び出された関数でエラーが発生した場合、Luaは元の関数に戻らず継続関数を呼び出す場合があります。この場合、lua_getctxの呼び出しはエラーコードを返し(lua_pcallkが返す値)、ctxの値はyieldの場合と同様にコンテキスト情報が設定されます。
lua_getfield
[-0, +1, e]
void lua_getfield (lua_State *L, int index, const char *k);指定されたインデックスの値tに対しt[k]の値をスタックにプッシュします。この関数はLua内と同様に「インデックス」イベントのメタメソッドをトリガーすることがあります(§2.4参照)。
lua_getglobal
[-0, +1, e]
void lua_getglobal (lua_State *L, const char *name);指定されたグローバルnameの値をスタックにプッシュします。
lua_getmetatable
[-0, +(0|1), –]
int lua_getmetatable (lua_State *L, int index);指定されたインデックスの値のメタテーブルをスタックにプッシュします。値がメタテーブルを持たない場合、関数は0を返し、スタックには何もプッシュされません。
lua_gettable
[-1, +1, e]
void lua_gettable (lua_State *L, int index);指定されたインデックスの値tに対し、スタックトップにあるキーkでt[k]の値をスタックにプッシュします。
この関数はキーをスタックからポップし、その場所に結果の値を配置します。Lua内と同様に、この関数は「インデックス」イベントのメタメソッドをトリガーすることがあります(§2.4参照)。
lua_gettop
[-0, +0, –]
int lua_gettop (lua_State *L);スタック内のトップ要素のインデックスを返します。インデックスは1から始まるため、この結果はスタック内の要素数と同じで、0は空のスタックを意味します。
lua_getuservalue
[-0, +1, –]
void lua_getuservalue (lua_State *L, int index);指定されたインデックスにあるユーザーデータに関連付けられたLuaの値をスタックにプッシュします。この値はテーブルまたはnilでなければなりません。
lua_insert
[-1, +1, –]
void lua_insert (lua_State *L, int index);スタックトップの要素を指定された有効なインデックスに移動し、このインデックス上の要素を上にシフトしてスペースを確保します。この関数は、擬似インデックスをスタック位置として使用できないため、擬似インデックスでは呼び出せません。
lua_Integer
typedef ptrdiff_t lua_Integer;Lua APIで符号付き整数値を表すために使用される型です。
デフォルトではptrdiff_tで、通常、マシンが「快適に」扱える最大の符号付き整数型です。
lua_isboolean
[-0, +0, –]
int lua_isboolean (lua_State *L, int index);指定されたインデックスの値がブール値であれば1を、そうでなければ0を返します。
lua_iscfunction
[-0, +0, –]
int lua_iscfunction (lua_State *L, int index);指定されたインデックスの値がC関数であれば1を、そうでなければ0を返します。
lua_isfunction
[-0, +0, –]
int lua_isfunction (lua_State *L, int index);指定されたインデックスの値が関数(CまたはLua関数)であれば1を、そうでなければ0を返します。
lua_islightuserdata
[-0, +0, –]
int lua_islightuserdata (lua_State *L, int index);指定されたインデックスの値がライトユーザーデータであれば1を、そうでなければ0を返します。
lua_isnil
[-0, +0, –]
int lua_isnil (lua_State *L, int index);指定されたインデックスの値がnilであれば1を、そうでなければ0を返します。
lua_isnone
[-0, +0, –]
int lua_isnone (lua_State *L, int index);指定されたインデックスが無効であれば1を、そうでなければ0を返します。
lua_isnoneornil
[-0, +0, –]
int lua_isnoneornil (lua_State *L, int index);指定されたインデックスが無効であるか、またはそのインデックスの値がnilであれば1を、そうでなければ0を返します。
lua_isnumber
[-0, +0, –]
int lua_isnumber (lua_State *L, int index);指定されたインデックスの値が数値、または数値に変換可能な文字列であれば1を、そうでなければ0を返します。
lua_isstring
[-0, +0, –]
int lua_isstring (lua_State *L, int index);指定されたインデックスの値が文字列、または文字列に変換可能な数値であれば1を、そうでなければ0を返します。
lua_istable
[-0, +0, –]
int lua_istable (lua_State *L, int index);指定されたインデックスの値がテーブルであれば1を、そうでなければ0を返します。
lua_isthread
[-0, +0, –]
int lua_isthread (lua_State *L, int index);指定されたインデックスの値がスレッドであれば1を、そうでなければ0を返します。
lua_isuserdata
[-0, +0, –]
int lua_isuserdata (lua_State *L, int index);指定されたインデックスの値がユーザーデータ(フルまたはライト)であれば1を、そうでなければ0を返します。
lua_len
[-0, +1, e]
void lua_len (lua_State *L, int index);指定されたインデックスの値の「長さ」を返します。これはLuaの#演算子と同等です(§3.4.6参照)。結果はスタックにプッシュされます。
lua_load
[-0, +1, –]
int lua_load (lua_State *L,
lua_Reader reader,
void *data,
const char *source,
const char *mode);Luaチャンクをロードします(実行はしません)。エラーがなければ、lua_loadはコンパイル済みのチャンクをLua関数としてスタックトップにプッシュします。エラーがあれば、エラーメッセージをプッシュします。
lua_loadの戻り値は以下の通りです:
LUA_OK: エラーなしLUA_ERRSYNTAX: 構文エラー(前処理中のエラー)LUA_ERRMEM: メモリ割り当てエラーLUA_ERRGCMM:__gcメタメソッド実行中のエラー(ロードされるチャンクとは無関係で、ガベージコレクタが生成します)
lua_load関数は、ユーザーが提供するリーダー関数を使用してチャンクを読み込みます(lua_Reader参照)。data引数はリーダー関数に渡される不透明な値です。
source引数は、エラーメッセージやデバッグ情報(§4.9参照)で使用されるチャンク名を指定します。
lua_loadは、チャンクがテキストかバイナリかを自動的に検出し、それに応じてロードします(luacプログラム参照)。文字列modeはload関数と同様に動作し、NULLは文字列"bt"と同等です。
lua_loadは内部でスタックを使用するため、リーダー関数は戻り時にスタックを変更しないようにする必要があります。
結果の関数が1つのアップバリューを持つ場合、このアップバリューはレジストリ内のインデックスLUA_RIDX_GLOBALSに保存されたグローバル環境の値に設定されます(§4.5参照)。メインチャンクをロードする場合、このアップバリューは_ENV変数になります(§2.2参照)。
lua_newstate
[-0, +0, –]
lua_State *lua_newstate (lua_Alloc f, void *ud);新しい、独立した状態で動作するスレッドを作成します。メモリ不足によりスレッドまたは状態を作成できない場合はNULLを返します。引数fはメモリ割り当て関数であり、Luaはこの関数を通じてメモリ割り当てを行います。2番目の引数udは、Luaが呼び出しごとにアロケータに渡す不透明なポインタです。
lua_newtable
[-0, +1, e]
void lua_newtable (lua_State *L);新しい空のテーブルを作成してスタックにプッシュします。これはlua_createtable(L, 0, 0)と同等です。
lua_newthread
[-0, +1, e]
lua_State *lua_newthread (lua_State *L);新しいスレッドを作成し、スタックにプッシュして、この新しいスレッドを表すlua_Stateへのポインタを返します。この関数で返される新しいスレッドは、元のスレッドとグローバル環境を共有しますが、独立した実行スタックを持っています。
スレッドを明示的に閉じたり破棄したりする関数はありません。スレッドは他のLuaオブジェクトと同様にガベージコレクションの対象になります。
lua_newuserdata
[-0, +1, e]
void *lua_newuserdata (lua_State *L, size_t size);指定されたサイズの新しいメモリブロックを割り当て、ブロックのアドレスを持つ新しいフルユーザーデータをスタックにプッシュし、そのアドレスを返します。このメモリはホストプログラムが自由に使用できます。
lua_next
[-1, +(2|0), e]
int lua_next (lua_State *L, int index);スタックからキーをポップし、指定されたインデックスのテーブルからキー–値のペアをプッシュします(指定したキーの「次の」ペア)。テーブルに要素が残っていない場合、lua_nextは0を返し、何もプッシュしません。
典型的なテーブルの走査は次のようになります:
/* テーブルはインデックス't'のスタックにあります */
lua_pushnil(L); /* 最初のキー */
while (lua_next(L, t) != 0) {
/* 'key'(インデックス-2)と 'value'(インデックス-1)を使用 */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* 'value'を削除し、次の反復のために 'key'を保持 */
lua_pop(L, 1);
}テーブルを走査中に、キーに直接lua_tolstringを呼び出さないでください。キーが実際に文字列であることが分かっている場合を除きます。lua_tolstringは指定されたインデックスの値を変更する可能性があるため、次のlua_next呼び出しが混乱する原因になります。
テーブル走査中にテーブルを変更する際の注意点については、next関数を参照してください。
lua_Number
typedef double lua_Number;Luaで使用される数値の型です。デフォルトではdoubleですが、luaconf.hで変更可能です。この設定ファイルを通じて、Luaの数値型を別の型(例えばfloatやlong)に変更することができます。
lua_pcall
[-(nargs + 1), +(nresults|1), –]
int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);保護モードで関数を呼び出します。
nargsとnresultsはlua_callと同じ意味を持ちます。呼び出し中にエラーがなければ、lua_pcallはlua_callと同様に動作します。しかし、エラーが発生した場合、lua_pcallはそのエラーをキャッチしてエラーメッセージをスタックにプッシュし、エラーコードを返します。lua_callと同様、関数とその引数はスタックから取り除かれます。
msghが0の場合、スタックに返されるエラーメッセージは元のエラーメッセージと同じです。それ以外の場合、msghはメッセージハンドラのスタックインデックスです(現在の実装では、このインデックスは擬似インデックスにはできません)。実行時エラーが発生すると、この関数はエラーメッセージを伴って呼び出され、その戻り値がlua_pcallによってスタックに返されるメッセージになります。
通常、メッセージハンドラはエラーメッセージにスタックトレースバックなどのデバッグ情報を追加するために使用されます。こうした情報は、lua_pcallの戻り後には収集できません。戻り時にはスタックが巻き戻されるためです。
lua_pcall関数は次のコードのいずれかを返します(lua.hで定義されています):
LUA_OK(0):成功LUA_ERRRUN: 実行時エラーLUA_ERRMEM: メモリ割り当てエラー。この場合、Luaはメッセージハンドラを呼び出しません。LUA_ERRERR: メッセージハンドラの実行中に発生したエラーLUA_ERRGCMM:__gcメタメソッドの実行中に発生したエラー(通常、このエラーは呼び出される関数とは関係なく、ガベージコレクタによって生成されます)
lua_pcallk
[-(nargs + 1), +(nresults|1), –]
int lua_pcallk (lua_State *L,
int nargs,
int nresults,
int errfunc,
int ctx,
lua_CFunction k);この関数はlua_pcallと同様に動作しますが、呼び出された関数がyieldできるようにします(§4.7参照)。
lua_pop
[-n, +0, –]
void lua_pop (lua_State *L, int n);スタックからn個の要素をポップします。
lua_pushboolean
[-0, +1, –]
void lua_pushboolean (lua_State *L, int b);ブール値bを持つ値をスタックにプッシュします。
lua_pushcclosure
[-n, +1, e]
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);新しいCクロージャをスタックにプッシュします。
C関数を作成する際にいくつかの値を関連付けることが可能で、これによりCクロージャを作成できます(§4.4参照)。これらの値は関数が呼び出されるときにアクセスできます。C関数に値を関連付けるには、まずこれらの値をスタックにプッシュします(複数の値がある場合、最初の値を最初にプッシュします)。次に、lua_pushcclosureを呼び出し、C関数をスタックにプッシュし、引数nで関数に関連付ける値の数を指定します。lua_pushcclosureはこれらの値をスタックからポップします。
nの最大値は255です。
nがゼロの場合、この関数はライトC関数を作成します。これは単なるC関数へのポインタです。この場合、メモリエラーをスローすることはありません。
lua_pushcfunction
[-0, +1, –]
void lua_pushcfunction (lua_State *L, lua_CFunction f);C関数をスタックにプッシュします。この関数はC関数へのポインタを受け取り、スタックに関数タイプのLua値をプッシュします。この値が呼び出されると、対応するC関数が実行されます。
Luaに登録される関数は、パラメータの受け取り方と結果の返し方について正しいプロトコルに従う必要があります(lua_CFunction参照)。
lua_pushcfunctionは以下のようにマクロとして定義されています:
#define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)このマクロでは、fが2回使用されます。
lua_pushfstring
[-0, +1, e]
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);フォーマットされた文字列をスタックにプッシュし、この文字列へのポインタを返します。これはISO Cのsprintf関数に似ていますが、いくつかの重要な違いがあります:
- 結果のメモリを確保する必要はありません。結果はLua文字列として扱われ、メモリの確保と解放(ガベージコレクションによる)はLuaが行います。
- 変換指定子は非常に制限されています。フラグ、幅、精度はなく、使用可能な指定子は次の通りです:
%%(文字列に%を挿入)、%s(サイズ制限のないゼロ終端文字列を挿入)、%f(lua_Numberを挿入)、%p(ポインタを16進数で挿入)、%d(intを挿入)、および%c(intをバイトとして挿入)。
lua_pushglobaltable
[-0, +1, –]
void lua_pushglobaltable (lua_State *L);グローバル環境をスタックにプッシュします。
lua_pushinteger
[-0, +1, –]
void lua_pushinteger (lua_State *L, lua_Integer n);値nを持つ整数をスタックにプッシュします。
lua_pushlightuserdata
[-0, +1, –]
void lua_pushlightuserdata (lua_State *L, void *p);ライトユーザーデータをスタックにプッシュします。
ユーザーデータはLua内でCの値を表現します。ライトユーザーデータはvoid*型のポインタで、個別のメタテーブルはなく、生成もされないためガベージコレクションの対象にはなりません。同じCアドレスを持つライトユーザーデータは等価とみなされます。
lua_pushliteral
[-0, +1, e]
const char *lua_pushliteral (lua_State *L, const char *s);このマクロはlua_pushlstringと同等ですが、sがリテラル文字列である場合にのみ使用できます。文字列の長さは自動的に計算されます。
lua_pushlstring
[-0, +1, e]
const char *lua_pushlstring (lua_State *L, const char *s, size_t len);サイズlenのchar配列sが指す文字列をスタックにプッシュします。Luaは指定された文字列の内部コピーを作成するため、関数の戻り後、sのメモリを解放または再利用できます。文字列は埋め込みのゼロを含む任意のバイナリデータが可能です。
内部コピーのポインタを返します。
lua_pushnil
[-0, +1, –]
void lua_pushnil (lua_State *L);nil値をスタックにプッシュします。
lua_pushnumber
[-0, +1, –]
void lua_pushnumber (lua_State *L, lua_Number n);値nを持つ数値をスタックにプッシュします。
lua_pushstring
[-0, +1, e]
const char *lua_pushstring (lua_State *L, const char *s);ゼロ終端文字列sが指す文字列をスタックにプッシュします。Luaは指定された文字列の内部コピーを作成するため、関数の戻り後、sのメモリを解放または再利用できます。
内部コピーのポインタを返します。
sがNULLの場合、nilをプッシュしてNULLを返します。
lua_pushthread
[-0, +1, –]
int lua_pushthread (lua_State *L);Lが表すスレッドをスタックにプッシュします。このスレッドがその状態のメインスレッドであれば1を返します。
lua_pushunsigned
[-0, +1, –]
void lua_pushunsigned (lua_State *L, lua_Unsigned n);値nを持つ符号なし整数をスタックにプッシュします。
lua_pushvalue
[-0, +1, –]
void lua_pushvalue (lua_State *L, int index);指定されたインデックスにある要素のコピーをスタックにプッシュします。
lua_pushvfstring
[-0, +1, e]
const char *lua_pushvfstring (lua_State *L,
const char *fmt,
va_list argp);lua_pushfstringと同等ですが、可変長引数の代わりにva_listを受け取ります。
lua_rawequal
[-0, +0, –]
int lua_rawequal (lua_State *L, int index1, int index2);インデックスindex1とindex2の2つの値が、メタメソッドを使用せずに素の等価であれば1を返します。それ以外の場合は0を返します。いずれかのインデックスが無効な場合も0を返します。
lua_rawget
[-1, +1, –]
void lua_rawget (lua_State *L, int index);lua_gettableに似ていますが、メタメソッドを使用せずに生のアクセスを行います。
lua_rawgeti
[-0, +1, –]
void lua_rawgeti (lua_State *L, int index, int n);指定されたインデックスにあるテーブルtに対しt[n]の値をスタックにプッシュします。アクセスはメタメソッドを呼び出さない生のアクセスです。
lua_rawgetp
[-0, +1, –]
void lua_rawgetp (lua_State *L, int index, const void *p);指定されたインデックスにあるテーブルtに対し、ポインタpをライトユーザーデータとして表現し、それをキーとするt[k]の値をスタックにプッシュします。アクセスはメタメソッドを呼び出さない生のアクセスです。
lua_rawlen
[-0, +0, –]
size_t lua_rawlen (lua_State *L, int index);指定されたインデックスにある値の生の「長さ」を返します。文字列の場合は文字列の長さ、テーブルの場合はメタメソッドを使用せずに長さ演算子(#)で得られる結果、ユーザーデータの場合は割り当てられたメモリブロックのサイズ、その他の値の場合は0を返します。
lua_rawset
[-2, +0, e]
void lua_rawset (lua_State *L, int index);lua_settableに似ていますが、メタメソッドを使用せずに生の代入を行います。
lua_rawseti
[-1, +0, e]
void lua_rawseti (lua_State *L, int index, int n);指定されたインデックスにあるテーブルtに対し、スタックトップの値vでt[n] = vを実行します。この関数は値をスタックからポップします。代入はメタメソッドを呼び出さない生の代入です。
lua_rawsetp
[-1, +0, e]
void lua_rawsetp (lua_State *L, int index, const void *p);指定されたインデックスにあるテーブルtに対し、ポインタpをライトユーザーデータとして表現し、スタックトップの値vでt[k] = vを実行します。この関数は値をスタックからポップします。代入はメタメソッドを呼び出さない生の代入です。
lua_Reader
typedef const char * (*lua_Reader) (lua_State *L,
void *data,
size_t *size);lua_loadで使用されるリーダー関数です。チャンクの別の部分が必要になるたびに、lua_loadはリーダーを呼び出し、そのdataパラメータを渡します。リーダーはチャンクの新しい部分を含むメモリブロックへのポインタを返し、sizeにブロックのサイズを設定しなければなりません。チャンクの終了を知らせるには、リーダーはNULLを返すか、sizeを0に設定します。リーダー関数は、ゼロより大きい任意のサイズの部分を返すことができます。
lua_register
[-0, +0, e]
void lua_register (lua_State *L, const char *name, lua_CFunction f);C関数fをグローバルnameの新しい値として設定します。これはマクロとして定義されています:
#define lua_register(L,n,f) \
(lua_pushcfunction(L, f), lua_setglobal(L, n))lua_remove
[-1, +0, –]
void lua_remove (lua_State *L, int index);指定されたインデックスにある要素を削除し、そのインデックスより上の要素を下にシフトして空きを埋めます。この関数は、スタック位置ではない擬似インデックスでは呼び出せません。
lua_replace
[-1, +0, –]
void lua_replace (lua_State *L, int index);スタックトップの要素を指定されたインデックスに移動し、他の要素をシフトせずにそのインデックスの値を置き換えます。その後、スタックトップの要素をポップします。
lua_resume
[-?, +?, –]
int lua_resume (lua_State *L, lua_State *from, int nargs);指定されたスレッドでコルーチンを開始および再開します。
コルーチンを開始するには、スレッドスタックにメイン関数と引数をプッシュし、引数の数をnargsに指定してlua_resumeを呼び出します。この呼び出しはコルーチンが一時停止または実行を完了した時点で戻ります。戻り時のスタックにはlua_yieldで渡されたすべての値、または本体関数から返されたすべての値が含まれます。lua_resumeは、コルーチンが一時停止した場合はLUA_YIELDを、エラーなく実行を完了した場合はLUA_OKを、エラーが発生した場合はエラーコードを返します(lua_pcall参照)。
エラーが発生した場合、スタックは巻き戻されないため、デバッグAPIを使用してエラーを調査できます。エラーメッセージはスタックのトップにあります。
コルーチンを再開するには、前回のlua_yieldの結果を削除し、スタックにyieldから返される値のみをプッシュしてからlua_resumeを呼び出します。
fromパラメータは、Lを再開するコルーチンを表します。コルーチンがない場合、このパラメータはNULLにできます。
lua_setallocf
[-0, +0, –]
void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);指定された状態のメモリアロケータ関数をfに変更し、ユーザーデータudを設定します。
lua_setfield
[-1, +0, e]
void lua_setfield (lua_State *L, int index, const char *k);指定されたインデックスにあるtに対してt[k] = vを実行します。ここでvはスタックトップの値です。
この関数はスタックから値をポップします。Luaと同様、この関数はnewindexイベントのメタメソッドを呼び出す可能性があります(§2.4参照)。
lua_setglobal
[-1, +0, e]
void lua_setglobal (lua_State *L, const char *name);スタックから値をポップし、それをグローバルnameの新しい値として設定します。
lua_setmetatable
[-1, +0, –]
void lua_setmetatable (lua_State *L, int index);スタックからテーブルをポップし、指定されたインデックスにある値の新しいメタテーブルとして設定します。
lua_settable
[-2, +0, e]
void lua_settable (lua_State *L, int index);指定されたインデックスにあるtに対してt[k] = vを実行します。ここで、vはスタックトップの値で、kはその下にある値です。
この関数はスタックからキーと値をポップします。Luaと同様、この関数はnewindexイベントのメタメソッドを呼び出す可能性があります(§2.4参照)。
lua_settop
[-?, +?, –]
void lua_settop (lua_State *L, int index);任意のインデックスまたは0を受け取り、スタックトップをこのインデックスに設定します。新しいトップが古いトップよりも大きい場合、新しい要素はnilで埋められます。indexが0の場合、スタックのすべての要素が削除されます。
lua_setuservalue
[-1, +0, –]
void lua_setuservalue (lua_State *L, int index);スタックからテーブルまたはnilをポップし、指定されたインデックスにあるユーザーデータに関連付けられた新しい値として設定します。
lua_State
typedef struct lua_State lua_State;Luaインタプリタ全体の状態を間接的に指すスレッドを表す不透明な構造体です。Luaライブラリは完全に再入可能で、グローバル変数を持ちません。状態に関するすべての情報はこの構造体を介してアクセスできます。
この構造体へのポインタは、lua_newstate(新しいLua状態を作成する関数)を除き、ライブラリ内のすべての関数の第一引数として渡される必要があります。
lua_status
[-0, +0, –]
int lua_status (lua_State *L);スレッドLの状態を返します。
状態は0(LUA_OK)であれば通常のスレッド、lua_resumeの実行完了時にエラーが発生した場合はエラーコード、スレッドが一時停止中であればLUA_YIELDです。
LUA_OK状態のスレッドでのみ関数を呼び出せます。LUA_OKまたはLUA_YIELD状態のスレッドは再開できます(新しいコルーチンの開始またはコルーチンの再開)。
lua_toboolean
[-0, +0, –]
int lua_toboolean (lua_State *L, int index);指定されたインデックスにあるLuaの値をCのブール値(0または1)に変換します。Luaにおけるすべてのテストと同様、falseとnil以外の値であればlua_tobooleanは真を返し、falseまたはnilであれば偽を返します。(実際のブール値のみを受け入れる場合は、値の型をテストするためにlua_isbooleanを使用してください。)
lua_tocfunction
[-0, +0, –]
lua_CFunction lua_tocfunction (lua_State *L, int index);指定されたインデックスの値をC関数に変換します。その値がC関数でなければ、NULLを返します。
lua_tointeger
[-0, +0, –]
lua_Integer lua_tointeger (lua_State *L, int index);lua_tointegerxと同等で、isnumがNULLと等しい場合の動作です。
lua_tointegerx
[-0, +0, –]
lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);指定されたインデックスのLuaの値を符号付き整数型lua_Integerに変換します。Luaの値が数値または数値に変換可能な文字列でなければ、lua_tointegerxは0を返します(§3.4.2参照)。
数値が整数でない場合は、非指定の方法で切り捨てられます。
isnumがNULLでない場合、変換が成功したかどうかを示すブール値が設定されます。
lua_tolstring
[-0, +0, e]
const char *lua_tolstring (lua_State *L, int index, size_t *len);指定されたインデックスのLuaの値をC文字列に変換します。lenがNULLでない場合、文字列の長さが*lenに設定されます。Luaの値が文字列または数値でなければ、この関数はNULLを返します。値が数値の場合、lua_tolstringはスタック上の実際の値を文字列に変更します(テーブルトラバーサル中にキーに対してlua_tolstringを適用すると、lua_nextが混乱する可能性があります)。
lua_tolstringはLua状態内の文字列への完全に整列されたポインタを返します。この文字列は、最後の文字の後に必ずゼロ('\0')が付きますが、内部に他のゼロを含むこともあります。Luaはガベージコレクションを行うため、対応する値がスタックから削除された後もlua_tolstringが返すポインタが有効である保証はありません。
lua_tonumber
[-0, +0, –]
lua_Number lua_tonumber (lua_State *L, int index);lua_tonumberxと同等で、isnumがNULLと等しい場合の動作です。
lua_tonumberx
[-0, +0, –]
lua_Number lua_tonumberx (lua_State *L, int index, int *isnum);指定されたインデックスのLuaの値をC型lua_Numberに変換します(lua_Number参照)。Luaの値が数値または数値に変換可能な文字列でなければ、lua_tonumberxは0を返します(§3.4.2参照)。
isnumがNULLでない場合、変換が成功したかどうかを示すブール値が設定されます。
lua_topointer
[-0, +0, –]
const void *lua_topointer (lua_State *L, int index);指定されたインデックスの値を汎用Cポインタ(void*)に変換します。値はユーザーデータ、テーブル、スレッド、または関数である必要があります。それ以外の場合、lua_topointerはNULLを返します。異なるオブジェクトは異なるポインタを生成します。このポインタを元の値に戻す方法はありません。
この関数は通常、デバッグ情報にのみ使用されます。
lua_tostring
[-0, +0, e]
const char *lua_tostring (lua_State *L, int index);lua_tolstringと同等で、lenがNULLと等しい場合の動作です。
lua_tothread
[-0, +0, –]
lua_State *lua_tothread (lua_State *L, int index);指定されたインデックスの値をLuaスレッド(lua_State*として表現)に変換します。この値がスレッドでなければ、関数はNULLを返します。
lua_tounsigned
[-0, +0, –]
lua_Unsigned lua_tounsigned (lua_State *L, int index);lua_tounsignedxと同等で、isnumがNULLと等しい場合の動作です。
lua_tounsignedx
[-0, +0, –]
lua_Unsigned lua_tounsignedx (lua_State *L, int index, int *isnum);指定されたインデックスのLuaの値を符号なし整数型lua_Unsignedに変換します。Luaの値が数値または数値に変換可能な文字列でなければ、lua_tounsignedxは0を返します(§3.4.2参照)。
数値が整数でない場合は、非指定の方法で切り捨てられます。数値が表現可能な範囲外である場合、最大表現値に1を加えた値で割った余りに正規化されます。
isnumがNULLでない場合、変換が成功したかどうかを示すブール値が設定されます。
lua_touserdata
[-0, +0, –]
void *lua_touserdata (lua_State *L, int index);指定されたインデックスの値がフルユーザーデータの場合、そのブロックアドレスを返します。値がライトユーザーデータである場合、そのポインタを返します。それ以外の場合はNULLを返します。
lua_type
[-0, +0, –]
int lua_type (lua_State *L, int index);指定された有効なインデックスの値の型を返します。インデックスが無効(ただし許容範囲)であればLUA_TNONEを返します。lua_typeが返す型は、lua.hで定義された以下の定数で表されます:LUA_TNIL、LUA_TNUMBER、LUA_TBOOLEAN、LUA_TSTRING、LUA_TTABLE、LUA_TFUNCTION、LUA_TUSERDATA、LUA_TTHREAD、およびLUA_TLIGHTUSERDATA。
lua_typename
[-0, +0, –]
const char *lua_typename (lua_State *L, int tp);lua_typeが返す値のうちtpでエンコードされた型の名前を返します。
lua_Unsigned
typedef unsigned long lua_Unsigned;Lua APIで符号なし整数値を表すために使用される型です。少なくとも32ビットの範囲を持つ必要があります。
デフォルトではunsigned intまたはunsigned longのいずれかで、32ビットの値を保持できる方が選択されます。
lua_upvalueindex
[-0, +0, –]
int lua_upvalueindex (int i);実行中の関数のi番目のアップバリューを表す擬似インデックスを返します(§4.4参照)。
lua_version
[-0, +0, v]
const lua_Number *lua_version (lua_State *L);Luaコアに格納されたバージョン番号のアドレスを返します。lua_Stateが有効である場合、作成された状態のバージョンのアドレスを返します。NULLで呼び出すと、呼び出しを行っているバージョンのアドレスを返します。
lua_Writer
typedef int (*lua_Writer) (lua_State *L,
const void* p,
size_t sz,
void* ud);lua_dumpで使用されるライター関数の型です。チャンクの別の部分が生成されるたびに、lua_dumpはバッファpとそのサイズsz、およびlua_dumpに渡されたデータパラメータをライターに渡します。
ライターはエラーコードを返します。0はエラーがないことを示し、他の値はエラーが発生したことを示し、lua_dumpがライターを再度呼び出さないようにします。
lua_xmove
[-?, +?, –]
void lua_xmove (lua_State *from, lua_State *to, int n);同じ状態の異なるスレッド間で値を交換します。
この関数はfromのスタックからn個の値をポップし、それらをtoのスタックにプッシュします。
lua_yield
[-?, +?, –]
int lua_yield (lua_State *L, int nresults);この関数はlua_yieldkと同等ですが、継続関数は持ちません(§4.7参照)。したがって、スレッドが再開されると、lua_yieldを呼び出した関数を呼び出した関数に戻ります。
lua_yieldk
[-?, +?, –]
int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k);コルーチンを一時停止させます。
この関数はC関数の戻り値としてのみ呼び出す必要があります。以下のようにします:
return lua_yieldk (L, n, i, k);C関数がこのようにlua_yieldkを呼び出すと、実行中のコルーチンは実行を一時停止し、このコルーチンを開始したlua_resumeの呼び出しが戻ります。nresultsは、lua_resumeに結果として渡されるスタック上の値の数です。
コルーチンが再開されると、Luaは指定された継続関数kを呼び出し、lua_yieldkを呼び出したC関数の実行を再開します(§4.7参照)。継続関数は、前の関数のスタックと同じスタックを受け取り、結果が削除され、lua_resumeに渡された引数が代わりに置かれます。さらに、継続関数はlua_getctxを呼び出してctxの値にアクセスできます。
4.9 – デバッグインターフェース
Luaには組み込みのデバッグ機能はありませんが、関数とフックを介して特別なインターフェースを提供しています。このインターフェースにより、デバッガー、プロファイラー、その他のインタープリタから「内部情報」を取得するツールを構築することができます。
lua_Debug
typedef struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) */
const char *what; /* (S) */
const char *source; /* (S) */
int currentline; /* (l) */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
unsigned char nups; /* (u) アップバリューの数 */
unsigned char nparams; /* (u) パラメータの数 */
char isvararg; /* (u) */
char istailcall; /* (t) */
char short_src[LUA_IDSIZE]; /* (S) */
/* プライベート部分 */
other fields
} lua_Debug;lua_Debugは、関数やアクティベーションレコードに関するさまざまな情報を保持するための構造体です。lua_getstackは、この構造体のプライベート部分のみを後で使用するために設定します。lua_Debugの他のフィールドに有用な情報を設定するには、lua_getinfoを呼び出します。
lua_Debugのフィールドの意味は以下のとおりです:
- source: 関数を作成したチャンクのソースです。
sourceが@で始まる場合、その関数がファイル内で定義されており、@の後にファイル名が続きます。sourceが=で始まる場合、それ以降の内容がユーザーに依存する形でソースを説明します。それ以外の場合、関数は文字列内で定義されており、sourceはその文字列になります。 - short_src: エラーメッセージに使用される
sourceの「表示可能な」バージョンです。 - linedefined: 関数定義が始まる行番号です。
- lastlinedefined: 関数定義が終わる行番号です。
- what: 関数がLua関数の場合は"Lua"、C関数の場合は"C"、チャンクのメイン部分の場合は"main"という文字列です。
- currentline: 指定された関数が現在実行している行です。行情報がない場合、
currentlineは-1に設定されます。 - name: 指定された関数の適切な名前です。Luaでは関数は第一級の値であるため、固定された名前がありません。ある関数は複数のグローバル変数の値であったり、テーブルフィールドにのみ格納されていることがあります。
lua_getinfoは関数がどのように呼び出されたかを調べ、適切な名前を見つけようとします。名前が見つからない場合、nameはNULLに設定されます。 - namewhat:
nameフィールドの説明です。関数が呼び出された方法に応じて、namewhatの値は"global"、"local"、"method"、"field"、"upvalue"、または""(空文字列)になります(Luaは他のオプションが適用できない場合に空文字列を使用します)。 - istailcall: この関数呼び出しが末尾呼び出しであれば
trueです。この場合、このレベルの呼び出し元はスタックにありません。 - nups: 関数のアップバリューの数です。
- nparams: 関数の固定パラメータの数(C関数の場合は常に0)です。
- isvararg: 関数が可変引数関数であれば
trueです(C関数の場合は常にtrue)。
lua_gethook
[-0, +0, –]
lua_Hook lua_gethook (lua_State *L);現在のフック関数を返します。
lua_gethookcount
[-0, +0, –]
int lua_gethookcount (lua_State *L);現在のフックカウントを返します。
lua_gethookmask
[-0, +0, –]
int lua_gethookmask (lua_State *L);現在のフックマスクを返します。
lua_getinfo
[-(0|1), +(0|1|2), e]
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);特定の関数や関数の呼び出しに関する情報を取得します。
関数呼び出しに関する情報を得るには、arパラメータはlua_getstackの以前の呼び出しによって設定された有効なアクティベーションレコードである必要があります。または、フックに引数として渡されたものである必要があります(lua_Hook参照)。
関数に関する情報を取得するには、その関数をスタックにプッシュし、what文字列を>で始めます。(この場合、lua_getinfoはスタックのトップから関数をポップします)。例えば、関数fがどの行で定義されているかを知りたい場合、以下のコードを記述します:
lua_Debug ar;
lua_getglobal(L, "f"); /* グローバル 'f' を取得 */
lua_getinfo(L, ">S", &ar);
printf("%d\n", ar.linedefined);文字列whatの各文字は、構造体arのフィールドを設定するか、スタックに値をプッシュするために使用されます:
'n': フィールドnameとnamewhatを設定します。'S': フィールドsource、short_src、linedefined、lastlinedefined、およびwhatを設定します。'l': フィールドcurrentlineを設定します。't': フィールドistailcallを設定します。'u': フィールドnups、nparams、およびisvarargを設定します。'f': 指定されたレベルで実行中の関数をスタックにプッシュします。'L': インデックスがその関数で有効な行番号を示すテーブルをスタックにプッシュします。(有効な行とは、ブレークポイントを設定できるコードが関連付けられている行を指します。空行やコメントは非有効行です)
エラーが発生した場合(例えばwhatに無効なオプションがある場合)、この関数は0を返します。
lua_getlocal
[-0, +(0|1), –]
const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);指定されたアクティベーションレコードまたは関数のローカル変数に関する情報を取得します。
最初のケースでは、arパラメータはlua_getstackの以前の呼び出しによって設定された有効なアクティベーションレコードである必要があります。または、フックに引数として渡されたものである必要があります(lua_Hook参照)。インデックスnは調べるローカル変数を選択します。変数のインデックスと名前に関する詳細はdebug.getlocalを参照してください。
lua_getlocalは変数の値をスタックにプッシュし、その名前を返します。
第2のケースでは、arはNULLである必要があり、調査する関数はスタックのトップになければなりません。この場合、可視なのはLua関数のパラメータのみで(どの変数がアクティブであるかの情報がないため)、スタックには何もプッシュされません。
インデックスがアクティブなローカル変数の数を超える場合、NULLを返し(かつ何もプッシュされません)。
lua_getstack
[-0, +0, –]
int lua_getstack (lua_State *L, int level, lua_Debug *ar);インタプリタの実行時スタックに関する情報を取得します。
この関数は、指定されたレベルで実行中の関数のアクティベーションレコードを識別するための情報をlua_Debug構造体に設定します。レベル0は現在実行中の関数を指し、レベルn+1はレベルnを呼び出した関数を指します(ただし、末尾呼び出しはスタックにカウントされません)。エラーがない場合、lua_getstackは1を返します。スタック深度を超えるレベルで呼び出すと、0を返します。
lua_getupvalue
[-0, +(0|1), –]
const char *lua_getupvalue (lua_State *L, int funcindex, int n);クロージャのアップバリューに関する情報を取得します。(Lua関数において、アップバリューは関数が使用する外部のローカル変数であり、結果としてクロージャに含まれます)。lua_getupvalueはアップバリューのインデックスnを取得し、その値をスタックにプッシュして名前を返します。funcindexはスタック内のクロージャを指します。(アップバリューは特定の順序を持たず、関数全体でアクティブなため、任意の順序で番号が付けられます)。
インデックスがアップバリューの数を超える場合、NULLを返し(かつ何もプッシュされません)。C関数の場合、すべてのアップバリューに対して空文字列""が名前として使用されます。
lua_Hook
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);デバッグフック関数のための型。
フックが呼び出されると、ar引数のフィールドeventにはフックを引き起こした特定のイベントが設定されます。Luaはこれらのイベントを次の定数で識別します:LUA_HOOKCALL、LUA_HOOKRET、LUA_HOOKTAILCALL、LUA_HOOKLINE、およびLUA_HOOKCOUNT。さらに、行イベントの場合、フィールドcurrentlineも設定されます。他のフィールドの値を取得するには、フックがlua_getinfoを呼び出す必要があります。
呼び出しイベントにおいて、eventは通常の値であるLUA_HOOKCALLか、または末尾呼び出しのLUA_HOOKTAILCALLになります。この場合、対応する戻りイベントは発生しません。
Luaがフックを実行中のときは、他のフックへの呼び出しを無効にします。したがって、フックが関数またはチャンクを実行するためにLuaを再度呼び出す場合、この実行中には他のフックは呼び出されません。
フック関数には継続(continuations)はありません。つまり、lua_yieldk、lua_pcallk、またはlua_callkを非NULLのkと共に呼び出すことはできません。
フック関数は以下の条件でのみyieldできます。カウントと行イベントのみがyieldでき、いかなる値もyieldできません。フック関数がyieldするには、nresultsをゼロに設定してlua_yieldを呼び出して実行を終了する必要があります。
lua_sethook
int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);デバッグフック関数を設定します。
引数fはフック関数です。maskはフックが呼び出されるイベントを指定します。maskは、LUA_MASKCALL、LUA_MASKRET、LUA_MASKLINE、およびLUA_MASKCOUNTのビットごとの論理和で構成されます。count引数は、maskにLUA_MASKCOUNTが含まれる場合にのみ意味を持ちます。各イベントに対するフックの呼び出しは以下のように行われます:
- 呼び出しフック:インタプリタが関数を呼び出すときに呼び出されます。フックはLuaが新しい関数に入った直後、関数が引数を受け取る前に呼び出されます。
- 戻りフック:インタプリタが関数から戻るときに呼び出されます。フックはLuaが関数を終了する直前に呼び出されます。戻り値にアクセスする標準的な方法はありません。
- 行フック:インタプリタが新しい行のコードを実行しようとしているとき、またはコードが同じ行に戻るときに呼び出されます。(このイベントは、LuaがLua関数を実行中のときにのみ発生します)。
- カウントフック:インタプリタが
count回の命令を実行した後に呼び出されます。(このイベントもLua関数の実行中にのみ発生します)。
フックを無効にするには、maskをゼロに設定します。
lua_setlocal
const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);指定されたアクティベーションレコードのローカル変数の値を設定します。パラメータarとnはlua_getlocalと同様です(lua_getlocal参照)。lua_setlocalはスタックのトップにある値を変数に割り当て、その名前を返します。また、値をスタックからポップします。
インデックスがアクティブなローカル変数の数を超える場合、NULLを返し(何もポップしません)。
lua_setupvalue
const char *lua_setupvalue (lua_State *L, int funcindex, int n);クロージャのアップバリューの値を設定します。lua_setupvalueはスタックのトップにある値をアップバリューに割り当て、その名前を返します。また、値をスタックからポップします。パラメータfuncindexとnはlua_getupvalueと同様です(lua_getupvalue参照)。
インデックスがアップバリューの数を超える場合、NULLを返し(何もポップしません)。
lua_upvalueid
void *lua_upvalueid (lua_State *L, int funcindex, int n);インデックスfuncindexのクロージャからアップバリュー番号nの一意な識別子を返します。パラメータfuncindexとnはlua_getupvalueと同様です(lua_getupvalue参照)(ただし、nはアップバリューの数を超えてはなりません)。
この一意な識別子により、プログラムは異なるクロージャがアップバリューを共有しているかどうかを確認できます。Luaクロージャがアップバリュー(同一の外部ローカル変数を参照)を共有している場合、これらのアップバリューインデックスに対して同一のIDが返されます。
lua_upvaluejoin
void lua_upvaluejoin (lua_State *L, int funcindex1, int n1,
int funcindex2, int n2);インデックスfuncindex1のLuaクロージャのn1番目のアップバリューを、インデックスfuncindex2のLuaクロージャのn2番目のアップバリューに関連付けます。
5 – 補助ライブラリ
補助ライブラリは、CとLuaのインターフェースをとるための便利な関数をいくつか提供します。基本APIがCとLua間の全てのやりとりのための基本的な関数を提供しているのに対し、補助ライブラリは一般的なタスクを簡便に行うための高レベルな関数を提供します。
補助ライブラリの全ての関数や型は、ヘッダファイルlauxlib.hに定義されており、luaL_というプレフィックスが付けられています。
補助ライブラリ内の全ての関数は基本APIの上に構築されており、基本APIで実行できる全ての操作を行えます。とはいえ、補助ライブラリを使用することでコードに一貫性がもたらされます。
補助ライブラリのいくつかの関数は、内部で追加のスタックスロットを使用します。補助ライブラリの関数が5つ未満のスロットを使用する場合、スタックサイズをチェックせず、十分なスロットがあると仮定して動作します。
補助ライブラリ内の関数のいくつかは、C関数の引数チェックに使用されます。これらの関数は、引数に対してフォーマットされたエラーメッセージ(例えば「不正な引数 #1」)を表示するため、他のスタック値には使用しないようにしてください。
luaL_check*という名前の関数は、チェックが満たされない場合、必ずエラーを発生させます。
5.1 – 関数と型
以下に、補助ライブラリの関数と型をアルファベット順で一覧表示します。
luaL_addchar
void luaL_addchar (luaL_Buffer *B, char c);バッファB(luaL_Bufferを参照)にバイトcを追加します。
luaL_addlstring
void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);バッファB(luaL_Bufferを参照)に長さlの文字列sを追加します。この文字列にはゼロ(\0)が含まれていても構いません。
luaL_addsize
void luaL_addsize (luaL_Buffer *B, size_t n);バッファB(luaL_Bufferを参照)に、luaL_prepbufferを使用して事前にバッファ領域にコピーされた長さnの文字列を追加します。
luaL_addstring
void luaL_addstring (luaL_Buffer *B, const char *s);バッファB(luaL_Bufferを参照)にヌル終端文字列sを追加します。この文字列にはゼロ(\0)が含まれていない必要があります。
luaL_addvalue
void luaL_addvalue (luaL_Buffer *B);スタックのトップにある値をバッファB(luaL_Bufferを参照)に追加します。この関数は値をポップします。
この関数は文字列バッファに対して、スタック上に追加する値がある状態で唯一呼び出すことができる(そして呼び出さなければならない)関数です。
luaL_argcheck
void luaL_argcheck (lua_State *L,
int cond,
int arg,
const char *extramsg);条件condが真かどうかをチェックします。真でない場合、標準のエラーメッセージを表示してエラーを発生させます。
luaL_argerror
int luaL_argerror (lua_State *L, int arg, const char *extramsg);標準メッセージにextramsgを追加したエラーを発生させます。
この関数は決して戻りませんが、C関数内でreturn luaL_argerror(args)のように使用するのが一般的です。
luaL_Buffer
typedef struct luaL_Buffer luaL_Buffer;文字列バッファの型です。
文字列バッファを使用すると、CコードでLuaの文字列を部分ごとに構築することができます。使用パターンは以下の通りです:
luaL_Buffer型の変数bを宣言します。luaL_buffinit(L, &b)を呼び出して初期化します。luaL_add*関数を使ってバッファに文字列のパーツを追加します。luaL_pushresult(&b)を呼び出して、最終的な文字列をスタックのトップにプッシュします。
もし事前に結果の文字列の合計サイズがわかっている場合は、以下のように使用できます:
luaL_Buffer型の変数bを宣言します。luaL_buffinitsize(L, &b, sz)を呼び出して初期化し、サイズszのスペースを事前に確保します。- そのスペースに文字列をコピーします。
luaL_pushresultsize(&b, sz)を呼び出し、コピーされた結果の文字列の合計サイズszを指定します。
通常の操作中、文字列バッファは変動する数のスタックスロットを使用します。そのため、バッファを使用中は、スタックのトップがどこにあるかを把握しているとは限りません。バッファ操作の間にスタックを使うことは可能ですが、それはバランスが取れている場合に限られます。つまり、バッファ操作を呼び出した際、直前のバッファ操作直後のスタックレベルと同じレベルである必要があります(このルールの唯一の例外はluaL_addvalueです)。luaL_pushresultを呼び出した後、スタックはバッファが初期化されたときのレベルに戻り、そのトップに最終的な文字列がプッシュされます。
luaL_buffinit
void luaL_buffinit (lua_State *L, luaL_Buffer *B);バッファBを初期化します。この関数はスペースを割り当てません。バッファは変数として宣言する必要があります(luaL_Bufferを参照)。
luaL_buffinitsize
char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz);luaL_buffinitとluaL_prepbuffsizeのシーケンスに相当します。
luaL_callmeta
int luaL_callmeta (lua_State *L, int obj, const char *e);メタメソッドを呼び出します。
インデックスobjのオブジェクトがメタテーブルを持ち、そのメタテーブルにフィールドeがある場合、このフィールドを呼び出し、オブジェクトを唯一の引数として渡します。この場合、この関数はtrueを返し、呼び出しの結果をスタックにプッシュします。メタテーブルやメタメソッドがない場合、この関数はfalseを返し(スタックには何もプッシュしません)。
luaL_checkany
void luaL_checkany (lua_State *L, int arg);関数が位置argに任意の型(nilを含む)の引数を持っているかをチェックします。
luaL_checkint
int luaL_checkint (lua_State *L, int arg);関数引数argが数値かどうかをチェックし、この数値をintにキャストして返します。
luaL_checkinteger
lua_Integer luaL_checkinteger (lua_State *L, int arg);関数引数argが数値かどうかをチェックし、この数値をlua_Integerにキャストして返します。
luaL_checklong
long luaL_checklong (lua_State *L, int arg);関数引数argが数値かどうかをチェックし、この数値をlongにキャストして返します。
luaL_checklstring
const char *luaL_checklstring (lua_State *L, int arg, size_t *l);関数引数argが文字列かどうかをチェックし、この文字列を返します。lがNULLでない場合は、*lに文字列の長さを格納します。
この関数はlua_tolstringを使用して結果を取得するため、その関数の変換や注意点が適用されます。
luaL_checknumber
lua_Number luaL_checknumber (lua_State *L, int arg);関数引数argが数値かどうかをチェックし、この数値を返します。
luaL_checkoption
int luaL_checkoption (lua_State *L,
int arg,
const char *def,
const char *const lst[]);関数引数argが文字列かどうかをチェックし、この文字列が配列lst(NULLで終端されている必要があります)にあるかを検索します。文字列が見つかった場合、配列のインデックスを返します。引数が文字列でないか、文字列が見つからない場合はエラーを発生させます。
defがNULLでない場合、引数argが存在しない、またはこの引数がnilの場合にデフォルト値としてdefを使用します。
これは文字列をCの列挙型(enum)にマッピングするのに便利な関数です(Luaライブラリでは通常、数値の代わりにオプションの選択に文字列を使用するのが一般的です)。
luaL_checkstack
void luaL_checkstack (lua_State *L, int sz, const char *msg);スタックサイズをtop + sz要素まで拡張します。スタックがそのサイズまで拡張できない場合、エラーを発生させます。msgはエラーメッセージに追加されるテキストで、追加のテキストが不要な場合はNULLに設定します。
luaL_checkstring
const char *luaL_checkstring (lua_State *L, int arg);関数引数argが文字列かどうかをチェックし、この文字列を返します。この関数はlua_tolstringを使用して結果を取得するため、その関数の変換や注意点が適用されます。
luaL_checktype
void luaL_checktype (lua_State *L, int arg, int t);関数引数argが型tを持っているかどうかをチェックします。型tのエンコードはlua_typeを参照してください。
luaL_checkudata
void *luaL_checkudata (lua_State *L, int arg, const char *tname);関数引数argが型tnameのユーザデータかどうかをチェックし、ユーザデータのアドレスを返します(luaL_newmetatableおよびlua_touserdataを参照してください)。
luaL_checkunsigned
lua_Unsigned luaL_checkunsigned (lua_State *L, int arg);関数引数argが数値かどうかをチェックし、この数値をlua_Unsignedにキャストして返します。
luaL_checkversion
void luaL_checkversion (lua_State *L);呼び出しを行っているコア、Luaステートを作成したコア、および呼び出しを行っているコードが同じバージョンのLuaを使用しているかどうかをチェックします。また、呼び出しを行っているコアとLuaステートを作成したコアが同じアドレス空間を使用しているかもチェックします。
luaL_dofile
int luaL_dofile (lua_State *L, const char *filename);指定されたファイルをロードして実行します。この関数は次のマクロとして定義されています:
(luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))エラーがなければfalseを、エラーがあればtrueを返します。
luaL_dostring
int luaL_dostring (lua_State *L, const char *str);指定された文字列をロードして実行します。この関数は次のマクロとして定義されています:
(luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))エラーがなければfalseを、エラーがあればtrueを返します。
luaL_error
int luaL_error (lua_State *L, const char *fmt, ...);エラーを発生させます。エラーメッセージのフォーマットはfmtおよび追加の引数によって指定され、lua_pushfstringと同じ規則に従います。また、ファイル名とエラーが発生した行番号が利用可能であれば、メッセージの先頭に追加されます。この関数は返値を持たず、通常はC関数内でreturn luaL_error(args);という形で使用されます。
luaL_execresult
int luaL_execresult (lua_State *L, int stat);標準ライブラリのプロセス関連関数(os.executeやio.close)に対する戻り値を生成します。
luaL_fileresult
int luaL_fileresult (lua_State *L, int stat, const char *fname);標準ライブラリのファイル関連関数(io.open、os.rename、file:seekなど)に対する戻り値を生成します。
luaL_getmetafield
int luaL_getmetafield (lua_State *L, int obj, const char *e);インデックスobjのオブジェクトのメタテーブルからフィールドeをスタックにプッシュします。オブジェクトにメタテーブルがない場合や、そのフィールドがメタテーブルに存在しない場合はfalseを返し、何もプッシュしません。
luaL_getmetatable
void luaL_getmetatable (lua_State *L, const char *tname);レジストリ内で名前tnameに関連付けられたメタテーブルをスタックにプッシュします(luaL_newmetatableを参照してください)。
luaL_getsubtable
int luaL_getsubtable (lua_State *L, int idx, const char *fname);インデックスidxの値tにおいてt[fname]がテーブルであることを保証し、そのテーブルをスタックにプッシュします。既存のテーブルが見つかった場合はtrueを返し、新しいテーブルを作成した場合はfalseを返します。
luaL_gsub
const char *luaL_gsub (lua_State *L,
const char *s,
const char *p,
const char *r);文字列s内で文字列pが出現する箇所をすべて文字列rに置き換えたコピーを作成します。結果の文字列をスタックにプッシュし、これを返します。
luaL_len
int luaL_len (lua_State *L, int index);指定されたインデックスの値の「長さ」を数値として返します。これはLuaの#演算子と同等です(§3.4.6参照)。操作結果が数値でない場合、エラーを発生させます(この場合はメタメソッドを介した場合のみ発生します)。
luaL_loadbuffer
int luaL_loadbuffer (lua_State *L,
const char *buff,
size_t sz,
const char *name);luaL_loadbufferxと同等で、modeがNULLです。
luaL_loadbufferx
int luaL_loadbufferx (lua_State *L,
const char *buff,
size_t sz,
const char *name,
const char *mode);バッファをLuaチャンクとしてロードします。この関数はlua_loadを使用して、buffが指すバッファのサイズszを持つチャンクをロードします。
この関数はlua_loadと同じ結果を返します。nameはチャンクの名前で、デバッグ情報やエラーメッセージに使用されます。mode文字列はlua_loadと同様に動作します。
luaL_loadfile
int luaL_loadfile (lua_State *L, const char *filename);luaL_loadfilexと同等で、modeがNULLです。
luaL_loadfilex
int luaL_loadfilex (lua_State *L, const char *filename,
const char *mode);ファイルをLuaチャンクとしてロードします。この関数はlua_loadを使用して、指定されたファイル名filenameのファイル内のチャンクをロードします。filenameがNULLの場合は標準入力からロードします。ファイルの最初の行が#で始まる場合、その行は無視されます。
mode文字列はlua_loadと同様に動作します。
この関数はlua_loadと同じ結果を返しますが、ファイルを開いたり読み取ったりできない場合、またはファイルのモードが正しくない場合には追加のエラーコードLUA_ERRFILEを返します。
lua_loadと同様に、この関数はチャンクをロードするだけで、実行はしません。
luaL_loadstring
int luaL_loadstring (lua_State *L, const char *s);文字列をLuaチャンクとしてロードします。この関数はlua_loadを使用して、ヌル終端文字列sのチャンクをロードします。
この関数はlua_loadと同じ結果を返します。また、lua_loadと同様に、この関数はチャンクをロードするだけで、実行はしません。
luaL_newlib
void luaL_newlib (lua_State *L, const luaL_Reg *l);新しいテーブルを作成し、リストlにある関数を登録します。これは次のマクロとして実装されています:
(luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))luaL_newlibtable
void luaL_newlibtable (lua_State *L, const luaL_Reg l[]);配列l内のすべてのエントリを格納するのに最適なサイズの新しいテーブルを作成しますが、実際にはエントリは格納しません。これはluaL_setfuncsと組み合わせて使用されることを意図しています(luaL_newlib参照)。
これはマクロとして実装されています。配列lは実際の配列でなければならず、ポインタではありません。
luaL_newmetatable
int luaL_newmetatable (lua_State *L, const char *tname);レジストリにtnameキーが既にある場合は0を返します。それ以外の場合、ユーザデータのメタテーブルとして使用する新しいテーブルを作成し、それをtnameキーでレジストリに追加して1を返します。
どちらの場合も、最終的にtnameに関連付けられた値をスタックにプッシュします。
luaL_newstate
lua_State *luaL_newstate (void);新しいLuaステートを作成します。標準のCrealloc関数に基づいたアロケータを使用してlua_newstateを呼び出し、致命的エラーが発生した場合にエラーメッセージを標準エラー出力に出力するパニック関数を設定します(§4.6参照)。
新しいステートを返しますが、メモリアロケーションエラーが発生した場合はNULLを返します。
luaL_openlibs
void luaL_openlibs (lua_State *L);指定されたステートにすべての標準Luaライブラリを開きます。
luaL_optint
int luaL_optint (lua_State *L, int arg, int d);関数引数argが数値の場合、その数値をintにキャストして返します。この引数が存在しないかnilの場合はdを返します。その他の場合はエラーを発生させます。
luaL_optinteger
lua_Integer luaL_optinteger (lua_State *L,
int arg,
lua_Integer d);関数引数argが数値の場合、その数値をlua_Integerにキャストして返します。この引数が存在しないかnilの場合はdを返します。その他の場合はエラーを発生させます。
luaL_optlong
long luaL_optlong (lua_State *L, int arg, long d);関数引数argが数値の場合、その数値をlong型にキャストして返します。この引数が存在しないかnilの場合はdを返します。その他の場合はエラーを発生させます。
luaL_optlstring
const char *luaL_optlstring (lua_State *L,
int arg,
const char *d,
size_t *l);関数引数argが文字列の場合、その文字列を返します。この引数が存在しないかnilの場合はdを返します。その他の場合はエラーを発生させます。
lがNULLでない場合、結果の文字列の長さを*lに格納します。
luaL_optnumber
lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number d);関数引数argが数値の場合、その数値を返します。この引数が存在しないかnilの場合はdを返します。その他の場合はエラーを発生させます。
luaL_optstring
const char *luaL_optstring (lua_State *L,
int arg,
const char *d);関数引数argが文字列の場合、その文字列を返します。この引数が存在しないかnilの場合はdを返します。その他の場合はエラーを発生させます。
luaL_optunsigned
lua_Unsigned luaL_optunsigned (lua_State *L,
int arg,
lua_Unsigned u);関数引数argが数値の場合、その数値をlua_Unsigned型にキャストして返します。この引数が存在しないかnilの場合はuを返します。その他の場合はエラーを発生させます。
luaL_prepbuffer
char *luaL_prepbuffer (luaL_Buffer *B);luaL_prepbuffsizeと同等で、定義済みのサイズLUAL_BUFFERSIZEを使用します。
luaL_prepbuffsize
char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz);バッファB(luaL_Buffer参照)に追加する文字列をコピーできるサイズszのスペースのアドレスを返します。このスペースに文字列をコピーした後、luaL_addsizeを呼び出して文字列をバッファに実際に追加する必要があります。
luaL_pushresult
void luaL_pushresult (luaL_Buffer *B);バッファBの使用を終了し、最終的な文字列をスタックのトップに残します。
luaL_pushresultsize
void luaL_pushresultsize (luaL_Buffer *B, size_t sz);luaL_addsizeとluaL_pushresultのシーケンスと同等です。
luaL_ref
int luaL_ref (lua_State *L, int t);スタックのトップにあるオブジェクトに対して、インデックスtにあるテーブル内で参照を作成して返します(オブジェクトはポップされます)。
参照は一意の整数キーです。テーブルtに手動で整数キーを追加しない限り、luaL_refは一意のキーを保証します。参照rで参照されるオブジェクトは、lua_rawgeti(L, t, r)を呼び出すことで取得できます。関数luaL_unrefは参照とその関連オブジェクトを解放します。
スタックのトップのオブジェクトがnilの場合、luaL_refは定数LUA_REFNILを返します。定数LUA_NOREFは、luaL_refによって返される参照とは異なることが保証されています。
luaL_Reg
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;luaL_setfuncsによって登録される関数の配列の型です。nameは関数名で、funcは関数へのポインタです。luaL_Regの配列は、nameとfuncの両方がNULLである番兵エントリで終了する必要があります。
luaL_requiref
void luaL_requiref (lua_State *L, const char *modname,
lua_CFunction openf, int glb);関数openfを引数として文字列modnameで呼び出し、その呼び出し結果をpackage.loaded[modname]に設定します。これはその関数がrequireを通じて呼び出されたかのように動作します。
glbが真の場合、結果もグローバルmodnameに格納されます。
その結果のコピーをスタックに残します。
luaL_setfuncs
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);配列l(luaL_Reg参照)内のすべての関数をスタックのトップにあるテーブルに登録します(オプションのアップバリューの下に配置します。次を参照)。
nupがゼロでない場合、すべての関数はnup個のアップバリューを共有して作成され、それらの値はライブラリテーブルの上にスタックに事前にプッシュされる必要があります。登録後、これらの値はスタックからポップされます。
luaL_setmetatable
void luaL_setmetatable (lua_State *L, const char *tname);スタックのトップにあるオブジェクトのメタテーブルを、レジストリにtnameとして登録されているメタテーブルに設定します(luaL_newmetatable参照)。
luaL_testudata
void *luaL_testudata (lua_State *L, int arg, const char *tname);この関数はluaL_checkudataと同様に動作しますが、テストが失敗した場合にエラーを発生させる代わりにNULLを返します。
luaL_tolstring
const char *luaL_tolstring (lua_State *L, int idx, size_t *len);指定されたインデックスにある任意のLua値を、適切な形式でC文字列に変換します。変換結果の文字列はスタックにプッシュされ、この関数の戻り値としても返されます。lenがNULLでない場合、文字列の長さも*lenに設定されます。
値にメタテーブルがあり、そのメタテーブルに"__tostring"フィールドがある場合、luaL_tolstringは対応するメタメソッドを引数として呼び出し、その結果を返り値として使用します。
luaL_traceback
void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
int level);スタックL1のトレースバックを作成してプッシュします。msgがNULLでない場合、それがトレースバックの先頭に追加されます。levelパラメータはトレースバックの開始レベルを指定します。
luaL_typename
const char *luaL_typename (lua_State *L, int index);指定されたインデックスにある値の型名を返します。
luaL_unref
void luaL_unref (lua_State *L, int t, int ref);インデックスtのテーブルから参照refを解放します(luaL_ref参照)。エントリはテーブルから削除されるため、参照されたオブジェクトはガベージコレクションの対象となります。また、参照refは再利用可能として解放されます。
refがLUA_NOREFまたはLUA_REFNILの場合、luaL_unrefは何も行いません。
luaL_where
void luaL_where (lua_State *L, int lvl);現在のコールスタックにおけるレベルlvlでの位置を示す文字列をスタックにプッシュします。この文字列は通常、次の形式を持ちます:
chunkname:currentline:レベル0は実行中の関数で、レベル1は実行中の関数を呼び出した関数です。
この関数はエラーメッセージのプレフィックスを作成するために使用されます。
6 – 標準ライブラリ
Luaの標準ライブラリは、C APIを通じて直接実装された便利な関数を提供します。これらの関数の一部は、言語にとって不可欠なサービス(例:typeやgetmetatable)を提供し、他は「外部」サービス(例:I/O)にアクセスする機能を提供します。また、Luaで実装可能ですが、非常に有用であるか、重要なパフォーマンス要件があるためにCでの実装が望まれるもの(例:table.sort)もあります。
すべてのライブラリは公式のC APIを通じて実装され、個別のCモジュールとして提供されます。現在、Luaには以下の標準ライブラリがあります:
- 基本ライブラリ(§6.1)
- コルーチンライブラリ(§6.2)
- パッケージライブラリ(§6.3)
- 文字列操作(§6.4)
- テーブル操作(§6.5)
- 数学関数(例:
sin、logなど)(§6.6) - ビット演算(§6.7)
- 入出力(§6.8)
- OS関連機能(§6.9)
- デバッグ機能(§6.10)
基本ライブラリとパッケージライブラリを除き、各ライブラリはそのすべての関数をグローバルテーブルのフィールドまたはオブジェクトのメソッドとして提供します。
これらのライブラリにアクセスするには、CホストプログラムがluaL_openlibs関数を呼び出し、すべての標準ライブラリを開く必要があります。または、ホストプログラムが個別に開くこともでき、luaL_requirefを使用して、luaopen_base(基本ライブラリ用)、luaopen_package(パッケージライブラリ用)、luaopen_coroutine(コルーチンライブラリ用)、luaopen_string(文字列ライブラリ用)、luaopen_table(テーブルライブラリ用)、luaopen_math(数学ライブラリ用)、luaopen_bit32(ビットライブラリ用)、luaopen_io(I/Oライブラリ用)、luaopen_os(OSライブラリ用)、およびluaopen_debug(デバッグライブラリ用)を呼び出します。これらの関数はlualib.hで宣言されています。
6.1 – 基本関数
基本ライブラリはLuaにおけるコア機能を提供します。このライブラリをアプリケーションに含めない場合、いくつかの機能について独自の実装が必要かどうかを慎重に確認する必要があります。
assert (v [, message])
引数vがfalse(つまり、nilまたはfalse)の場合にエラーを発生させます。そうでない場合は、すべての引数をそのまま返します。messageはエラーメッセージとして使用され、不在の場合はデフォルトで「assertion failed!」が表示されます。
collectgarbage ([opt [, arg]])
この関数はガベージコレクタへの汎用インターフェースです。最初の引数optに応じて異なる動作を行います。
"collect":完全なガベージコレクションサイクルを実行します(デフォルトのオプション)。"stop":ガベージコレクタの自動実行を停止します。再開されるまで、明示的に呼び出された場合のみ実行されます。"restart":ガベージコレクタの自動実行を再開します。"count":Luaが使用中のメモリ量(Kバイト単位)と、メモリ量のバイト単位の1024での剰余を2つの値で返します。最初の値には小数部分が含まれるため、次の等式が常に成り立ちます。luak, b = collectgarbage("count") assert(k*1024 == math.floor(k)*1024 + b)(2番目の結果は、Luaが非浮動小数点型でコンパイルされた場合に有用です。)
"step":ガベージコレクションのステップを実行します。ステップ「サイズ」はargによって制御されますが、値が大きいほど多くのステップを実行します。適切なステップサイズを調整するにはargの値を実験的に調整する必要があります。この関数は、コレクションサイクルが終了した場合にtrueを返します。"setpause":コレクタの一時停止値として新しい値argを設定します(§2.5参照)。前の一時停止値を返します。"setstepmul":コレクタのステップ倍率として新しい値argを設定します(§2.5参照)。前のステップ倍率を返します。"isrunning":コレクタが実行中かどうかを示すブール値を返します(停止していない場合はtrue)。"generational":コレクタを世代別モードに変更します(これは実験的な機能です。§2.5参照)。"incremental":コレクタをインクリメンタルモードに変更します(デフォルトモード)。
dofile ([filename])
指定されたファイルを開き、その内容をLuaチャンクとして実行します。引数なしで呼び出された場合、標準入力(stdin)の内容を実行します。チャンクが返すすべての値を返します。エラーが発生した場合は、そのエラーを呼び出し元に伝搬させます(つまり、dofileは保護モードで実行されません)。
error (message [, level])
最後に呼び出された保護された関数を終了し、messageをエラーメッセージとして返します。error関数は決して戻り値を返しません。
通常、messageが文字列の場合、エラーの位置情報がメッセージの先頭に追加されます。level引数はエラー位置の特定方法を指定します。デフォルトの1ではerror関数が呼ばれた位置がエラー位置となり、2ではerrorを呼び出した関数の位置がエラー位置となります。levelに0を指定すると、エラーメッセージに位置情報が追加されません。
_G
グローバル変数(関数ではありません)で、グローバル環境を保持します(§2.2参照)。Lua自体はこの変数を使用せず、その値を変更しても環境には影響しませんし、その逆もありません。
getmetatable (object)
objectにメタテーブルがなければnilを返します。それ以外の場合、objectのメタテーブルに"__metatable"フィールドがある場合はその値を返し、ない場合は指定されたオブジェクトのメタテーブルを返します。
ipairs (t)
tが__ipairsというメタメソッドを持っている場合、そのメタメソッドをtを引数にして呼び出し、その結果の最初の3つの値を返します。
それ以外の場合は、以下の3つの値を返します:反復関数、テーブルt、および0。これにより、次の構文で
for i, v in ipairs(t) do body endテーブルのキー1, t[1]、2, t[2]、... など、最初に見つからなかった整数キーまで反復処理が行われます。
load (ld [, source [, mode [, env]]])
チャンクを読み込みます。
ldが文字列の場合、チャンクはその文字列です。ldが関数の場合、loadはこの関数を繰り返し呼び出してチャンクを取得します。各呼び出しでは、前回の結果と連結できる文字列を返す必要があります。空の文字列、nil、または何も返さない場合はチャンクの終了を意味します。
構文エラーがなければ、コンパイル済みのチャンクを関数として返します。エラーがある場合はnilとエラーメッセージを返します。
結果の関数にアップバリューがある場合、最初のアップバリューはenvの値に設定されます。envが指定されていない場合はグローバル環境の値が使用されます。(メインチャンクをロードする場合、結果の関数は常に1つのアップバリュー、つまり_ENV変数(§2.2参照)を持ちます。string.dumpで関数から生成されたバイナリチャンクをロードする場合、任意の数のアップバリューを持つことができます。)
sourceはエラーメッセージやデバッグ情報でチャンクのソースとして使用されます(§4.9参照)。省略時にはldが文字列の場合はldが使用され、それ以外の場合は"=(load)"が使用されます。
文字列modeはチャンクがテキストかバイナリ(プリコンパイルされたチャンク)かを制御します。"b"(バイナリのみ)、"t"(テキストのみ)、"bt"(両方)を指定できます。デフォルトは"bt"です。
loadfile ([filename [, mode [, env]]])
loadと似ていますが、チャンクをファイルfilenameまたはファイル名が指定されていない場合は標準入力から取得します。
next (table [, index])
テーブルのすべてのフィールドを順に処理するための関数です。最初の引数はテーブルで、2番目の引数はそのテーブルのインデックスです。nextはテーブルの次のインデックスとその関連する値を返します。2番目の引数としてnilを指定すると、nextは最初のインデックスとその値を返します。最後のインデックス、または空のテーブルにnilを指定すると、nextはnilを返します。2番目の引数が省略されると、nilとして扱われます。特に、next(t)を使用してテーブルが空かどうかを確認できます。
インデックスの列挙順は指定されていません(数値インデックスで処理する場合は、数値用のforループを使用してください)。
テーブルの処理中に存在しないフィールドに値を割り当てると、nextの動作は未定義になります。ただし、既存のフィールドの変更は可能です。特に、既存のフィールドをクリアすることができます。
pairs (t)
tが__pairsというメタメソッドを持っている場合、そのメタメソッドをtを引数にして呼び出し、その結果の最初の3つの値を返します。
それ以外の場合は、next関数、テーブルt、およびnilの3つの値を返し、以下の構文で
for k, v in pairs(t) do body endテーブルtのすべてのキーと値のペアを反復処理できます。
テーブルの処理中にテーブルを変更する際の注意点についてはnext関数を参照してください。
pcall (f [, arg1, ···])
指定された引数で関数fを保護モードで呼び出します。これにより、f内で発生するエラーは伝播されず、pcallがエラーをキャッチして状態コードを返します。最初の戻り値は状態コード(ブール値)で、エラーがなく正常に終了した場合はtrueです。この場合、pcallはこの最初の戻り値に続けて関数呼び出しの結果をすべて返します。エラーが発生した場合、pcallはfalseとエラーメッセージを返します。
print (···)
任意の数の引数を受け取り、それらの値を標準出力(stdout)に表示します。各引数はtostring関数を使用して文字列に変換されます。printは、フォーマットされた出力を意図したものではなく、デバッグなどで値を素早く表示するために使用されます。出力を完全に制御するには、string.formatとio.writeを使用してください。
rawequal (v1, v2)
メタメソッドを呼び出さずに、v1とv2が等しいかを確認します。ブール値を返します。
rawget (table, index)
メタメソッドを呼び出さずに、table[index]の実際の値を取得します。tableはテーブルでなければならず、indexは任意の値です。
rawlen (v)
オブジェクトvの長さを返します。vはテーブルまたは文字列でなければなりません。メタメソッドを呼び出さずに、整数値として返します。
rawset (table, index, value)
メタメソッドを呼び出さずに、table[index]にvalueを設定します。tableはテーブル、indexはnilやNaN以外の任意の値、valueは任意のLuaの値です。この関数はtableを返します。
select (index, ···)
indexが数値の場合、引数リストのindex番目以降のすべての引数を返します。負の数の場合は末尾から数え、-1は最後の引数を指します。それ以外の場合、indexは文字列"#"でなければならず、その場合は関数が受け取った追加の引数の総数を返します。
setmetatable (table, metatable)
指定されたテーブルに対してメタテーブルを設定します(Luaからは他の型のメタテーブルを変更できず、C言語からのみ可能です)。metatableがnilの場合、そのテーブルのメタテーブルを削除します。元のメタテーブルに"__metatable"フィールドがある場合、エラーを発生させます。
この関数はtableを返します。
tonumber (e [, base])
基数を指定しない場合、tonumberは引数を数値に変換しようとします。引数がすでに数値であるか、数値に変換可能な文字列(§3.4.2参照)の場合、その数値を返します。そうでなければ、nilを返します。
基数を指定した場合、eはその基数で解釈される整数値の文字列である必要があります。基数は2から36の間の整数で、10を超える基数の場合、大文字小文字にかかわらず'A'は10、'B'は11、…、'Z'は35を表します。指定された基数での数値表現として無効な文字列の場合、関数はnilを返します。
tostring (v)
任意の型の値を受け取り、適切な形式で文字列に変換します(数値の変換を完全に制御したい場合はstring.formatを使用してください)。vのメタテーブルに"__tostring"フィールドがある場合、その値をvを引数として呼び出し、その呼び出し結果を使用します。
type (v)
引数の型を文字列で返します。この関数が返す可能性のある結果は、"nil"(文字列であって値のnilではありません)、"number"、"string"、"boolean"、"table"、"function"、"thread"、および"userdata"です。
_VERSION
現在のインタプリタのバージョンを含む文字列を保持するグローバル変数です。現在の内容は"Lua 5.2"です。
xpcall (f, msgh [, arg1, ···])
この関数はpcallに似ていますが、新しいメッセージハンドラmsghを設定します。
6.2 コルーチンの操作
コルーチンに関連する操作は、基本ライブラリのサブライブラリとして提供され、coroutineテーブル内に格納されています。コルーチンの一般的な説明については§2.6を参照してください。
coroutine.create (f)
本体がfである新しいコルーチンを作成します。fはLua関数でなければなりません。新しいコルーチン(thread型のオブジェクト)を返します。
coroutine.resume (co [, val1, ···])
コルーチンcoの実行を開始または再開します。コルーチンを最初に再開すると、コルーチン本体が実行を開始します。val1などの値はコルーチンの本体関数への引数として渡されます。コルーチンが中断している場合、再開時にはそれらの値がyieldからの結果として渡されます。
コルーチンがエラーなく実行された場合、resumeはtrueおよびyieldで渡された値(コルーチンが中断した場合)または本体関数が返した値(コルーチンが終了した場合)を返します。エラーが発生した場合、falseとエラーメッセージを返します。
coroutine.running ()
実行中のコルーチンとブール値を返します。このブール値は、実行中のコルーチンがメインコルーチンである場合はtrueです。
coroutine.status (co)
コルーチンcoの状態を文字列で返します。コルーチンが実行中(statusを呼び出した場合)は"running"、yieldで中断された場合やまだ実行されていない場合は"suspended"、他のコルーチンを再開したが自分自身は実行されていない場合は"normal"、本体関数を実行し終えたかエラーで停止した場合は"dead"です。
coroutine.wrap (f)
本体がfである新しいコルーチンを作成します。fはLua関数でなければなりません。この関数は、呼び出されるたびにコルーチンを再開する関数を返します。呼び出しに渡された引数はresumeの追加引数として扱われます。resumeが返すのと同じ値を返し、最初のブール値を除きます。エラーが発生した場合、エラーが伝播されます。
coroutine.yield (···)
呼び出し元のコルーチンの実行を中断します。yieldへの引数はresumeへの追加の結果として渡されます。
6.3 モジュール
パッケージライブラリは、Luaにおけるモジュールの読み込み機能を提供します。グローバル環境にはrequireという関数が直接エクスポートされ、それ以外の機能はpackageテーブル内にエクスポートされます。
require (modname)
指定されたモジュールを読み込みます。この関数はまずpackage.loadedテーブルを確認し、modnameがすでに読み込まれているかを判断します。読み込まれている場合、requireはpackage.loaded[modname]に格納されている値を返します。読み込まれていない場合、モジュールのローダーを見つけようとします。
ローダーを見つけるために、requireはpackage.searchersシーケンスに従います。このシーケンスを変更することで、requireのモジュール検索方法を変更できます。以下は、package.searchersのデフォルト設定に基づいた説明です。
まず、requireはpackage.preload[modname]を調べます。値が存在する場合、この値(関数である必要があります)がローダーです。値がない場合、package.pathに保存されたパスを使ってLuaローダーを探します。それでも見つからない場合、package.cpathのパスを使ってCローダーを探します。これも失敗した場合、オールインワンローダーを試みます(詳細はpackage.searchersを参照)。
ローダーが見つかると、requireはそのローダーを引数modnameと、ローダーを取得した方法に依存する追加の値で呼び出します(ローダーがファイルから取得された場合、この追加の値はファイル名です)。ローダーが非nilの値を返すと、requireはその値をpackage.loaded[modname]に設定します。ローダーが非nilの値を返さず、かつpackage.loaded[modname]に値を設定していない場合、requireはこのエントリにtrueを設定します。いずれの場合でも、requireはpackage.loaded[modname]の最終値を返します。
モジュールの読み込みまたは実行中にエラーが発生した場合、またはローダーが見つからない場合、requireはエラーを発生させます。
package.config
パッケージに関するコンパイル時の設定を示す文字列。この文字列は、次のような行のシーケンスです。
- 最初の行はディレクトリの区切り文字です。デフォルトはWindowsでは
'\'、他のシステムでは'/'です。 - 2行目はパス内のテンプレートを区切る文字です。デフォルトは
';'です。 - 3行目はテンプレートの置換ポイントを示す文字列です。デフォルトは
'?'です。 - 4行目はWindowsのパスにおいて、実行ファイルのディレクトリに置き換えられる文字列です。デフォルトは
'!'です。 - 5行目は
luaopen_関数名を生成する際に無視するプレフィックスを示す文字列です。デフォルトは'-'です。
package.cpath
requireがCローダーを検索する際に使用するパスです。
LuaはCパスpackage.cpathをLuaパスpackage.pathと同様に初期化します。環境変数LUA_CPATH_5_2、またはLUA_CPATH、もしくはluaconf.hで定義されたデフォルトパスが使用されます。
package.loaded
requireが既に読み込まれたモジュールを管理するために使用するテーブル。requireがモジュールmodnameを読み込む際、package.loaded[modname]がfalseでない場合、requireはそこに格納されている値を単に返します。
この変数は実際のテーブルへの参照であり、この変数への代入はrequireが使用するテーブルには影響を与えません。
package.loadlib (libname, funcname)
ホストプログラムをCライブラリlibnameに動的にリンクします。
funcnameが"*"``の場合、ライブラリへのリンクのみ行い、ライブラリがエクスポートするシンボルを他の動的リンクライブラリが利用可能にします。それ以外の場合、ライブラリ内の関数funcnameを探し、この関数をC関数として返します。したがって、funcnameはlua_CFunctionプロトタイプに従っている必要があります(lua_CFunction`を参照)。
これは低レベルの関数であり、パッケージおよびモジュールシステムを完全にバイパスします。requireのようにパスの検索を行わず、自動で拡張子を追加もしません。libnameはCライブラリの完全なファイル名で、必要に応じてパスおよび拡張子を含める必要があります。funcnameもCライブラリがエクスポートする正確な名前でなければなりません(Cコンパイラやリンカに依存する場合があります)。
この関数は標準Cではサポートされていません。そのため、Windows、Linux、Mac OS X、Solaris、BSD、および他のdlfcn標準をサポートするUnixシステムなど、いくつかのプラットフォームでのみ使用可能です。
package.path
requireがLuaローダーを検索する際に使用するパスです。
起動時、Luaはこの変数を、環境変数LUA_PATH_5_2またはLUA_PATHの値で初期化します。これらの環境変数が定義されていない場合は、luaconf.hで定義されたデフォルトパスが使用されます。環境変数の値に;;が含まれている場合は、デフォルトパスに置き換えられます。
package.preload
特定のモジュールのローダーを格納するためのテーブル(requireを参照)。
この変数は実際のテーブルへの参照であり、この変数への代入はrequireが使用するテーブルに影響を与えません。
package.searchers
requireがモジュールをどのように読み込むかを制御するためのテーブルです。
このテーブルの各エントリは検索関数(サーチャー)です。requireはモジュールを探す際に、このテーブル内の各サーチャーを順番に、モジュール名(requireへの引数)を唯一のパラメータとして呼び出します。この関数は、モジュールローダーとなる別の関数と、ローダーに渡される追加の値を返すか、そのモジュールが見つからなかった理由を説明する文字列(または何も言うことがなければnil)を返します。
Luaはこのテーブルを、4つの検索関数で初期化します。
- 最初のサーチャーは、
package.preloadテーブルでローダーを探します。 - 2番目のサーチャーは、
package.pathに保存されたパスを使って、Luaライブラリとしてローダーを探します。検索は関数package.searchpathに従って行われます。 - 3番目のサーチャーは、
package.cpath変数で指定されたパスを使ってCライブラリとしてローダーを探します。検索は同様にpackage.searchpathに従って行われます。たとえば、Cパスが以下の文字列で指定されている場合、モジュール"./?.so;./?.dll;/usr/local/?/init.so"fooの検索では、./foo.so、./foo.dll、および/usr/local/foo/init.soという順序でファイルを開こうとします。Cライブラリが見つかると、このサーチャーはまず動的リンク機能を使用してアプリケーションとライブラリをリンクします。そして、ライブラリ内でローダーとして使用されるC関数を探します。このC関数の名前は、"luaopen_"にモジュール名の各ドットをアンダースコアに置換した文字列を連結したものです。さらに、モジュール名にハイフンが含まれている場合、最初のハイフンまでの接頭辞が削除されます。たとえば、モジュール名がa.v1-b.cの場合、関数名はluaopen_b_cとなります。 - 4番目のサーチャーはオールインワンローダーを試みます。指定されたモジュールのルート名でCライブラリを検索します。たとえば、
a.b.cを要求する場合、a用のCライブラリを検索します。見つかった場合、サブモジュールのオープン関数を探します。この例ではluaopen_a_b_cが対象となります。この機能により、1つのライブラリに複数のCサブモジュールをまとめることが可能になり、それぞれのサブモジュールは元のオープン関数を保持します。
最初のサーチャー(preload)を除くすべてのサーチャーは、追加の値としてpackage.searchpathから返されたモジュールが見つかったファイル名を返します。最初のサーチャーは追加の値を返しません。
package.searchpath (name, path [, sep [, rep]])
指定されたnameを指定されたpath内で検索します。
pathはセミコロンで区切られたテンプレートのシーケンスを含む文字列です。各テンプレートについて、テンプレート内の任意の疑問符(?)をnameのコピーで置換し、さらにname内のsep(デフォルトではドット)をrep(デフォルトではシステムのディレクトリ区切り文字)に置換してから、生成されたファイル名を開こうとします。
たとえば、pathが次のような文字列の場合、
"./?.lua;./?.lc;/usr/local/?/init.lua"foo.aという名前を検索すると、./foo/a.lua、./foo/a.lc、および/usr/local/foo/a/init.luaの順でファイルを開こうとします。
読み取りモードで最初に開けたファイルの名前を返します(ファイルは閉じられます)。どれも成功しなかった場合は、nilとエラーメッセージを返します(このエラーメッセージには試したすべてのファイル名が含まれます)。
6.4 – 文字列操作
このライブラリは、部分文字列の検索や抽出、パターンマッチングといった、汎用的な文字列操作の関数を提供します。Luaでは、文字列のインデックスは1から始まります(C言語のように0からではありません)。インデックスは負の値も使用でき、文字列の末尾から逆方向に数えられます。そのため、最後の文字は位置-1にあります。
文字列ライブラリのすべての関数はstringテーブル内に提供されています。また、文字列には__indexフィールドがstringテーブルを指すメタテーブルが設定されているため、オブジェクト指向スタイルで文字列関数を使用できます。例えば、string.byte(s, i)はs:byte(i)と記述できます。
この文字列ライブラリは、1バイトの文字エンコーディングを想定しています。
string.byte (s [, i [, j]])
文字列sの文字s[i]、s[i+1]、...、s[j]の内部数値コードを返します。iのデフォルト値は1、jのデフォルト値はiです。これらのインデックスはstring.sub関数と同じ規則で補正されます。 数値コードは、プラットフォーム間で移植性があるとは限りません。
string.char (···)
0個以上の整数を受け取ります。各引数に対応する内部数値コードを持つ文字を並べた、引数の数と同じ長さの文字列を返します。 数値コードは、プラットフォーム間で移植性があるとは限りません。
string.dump (function)
指定された関数のバイナリ表現を含む文字列を返します。この文字列を後で読み込むと、関数のコピーが返されます(ただし、新しいアップバリューを持ちます)。
string.find (s, pattern [, init [, plain]])
文字列s内で最初にpatternに一致する部分を探します。見つかった場合は、その開始位置と終了位置のインデックスを返し、見つからなければnilを返します。3番目のオプション引数initは、検索を開始する位置を指定します。デフォルトは1で、負の値も使用できます。4番目のオプション引数plainにtrueを指定すると、パターンマッチング機能をオフにし、パターン内のすべての文字を通常の文字列として扱って検索します。plainが指定される場合は、initも指定する必要があります。
パターンにキャプチャが含まれている場合、マッチが成功すると、2つのインデックスの後にキャプチャされた値も返されます。
string.format (formatstring, ···)
可変数の引数を指定された書式でフォーマットした文字列を返します。フォーマット文字列は、ISO Cのsprintf関数と同じ規則に従います。ただし、*、h、L、l、n、およびpのオプション/修飾子はサポートされていない点と、追加オプションとしてqが使用できる点が異なります。qオプションは文字列を二重引用符で囲み、必要に応じてエスケープシーケンスを使用して、Luaインタープリタが安全に読み込めるようにフォーマットします。例えば、
string.format('%q', 'a string with "quotes" and \n new line')とすると、次のような文字列が生成されることがあります:
"a string with \"quotes\" and \
new line"オプションAとa(使用可能な場合)、E、e、f、G、およびgは、引数として数値を期待します。オプションc、d、i、o、u、X、およびxも数値を期待しますが、その範囲は基礎となるCの実装によって制限される場合があります。オプションo、u、X、およびxでは負の数は許可されていません。オプションqは文字列を、オプションsは埋め込みゼロのない文字列を期待します。オプションsへの引数が文字列でない場合は、tostringと同じ規則で文字列に変換されます。
string.gmatch (s, pattern)
イテレータ関数を返します。この関数が呼び出されるたびに、文字列sからパターンpatternに一致する次のキャプチャを返します。パターンがキャプチャを指定していない場合は、各呼び出しでマッチ全体が返されます。
例えば、次のループは文字列s内のすべての単語を1行ずつ表示します:
s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do
print(w)
end次の例では、与えられた文字列からすべてのkey=valueペアをテーブルに格納します:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
endこの関数では、パターンの先頭にキャレット(^)を使用してもアンカーとして機能しません。これは、イテレーションを妨げるためです。
string.gsub (s, pattern, repl [, n])
string.gsubは、文字列sの中でpatternに一致するすべての部分(または指定されたn個まで)を、replで指定された置換文字列に置き換えたコピーを返します。また、マッチが発生した総数を第2の戻り値として返します。関数名のgsubは「Global SUBstitution」(全体置換)を意味します。
replが文字列の場合、その値が置換に使用されます。文字%はエスケープ文字として機能し、repl内の%d(dは1から9のいずれか)は、d番目のキャプチャされた部分文字列を表します。%0は全体のマッチを表し、%%は単一の%として扱われます。replがテーブルの場合、各マッチに対して最初のキャプチャをキーとしてテーブルを参照します。replが関数の場合、各マッチのたびにこの関数が呼び出され、すべてのキャプチャされた部分文字列が引数として渡されます。
いずれの場合も、パターンがキャプチャを指定していない場合、パターン全体がキャプチャ内にあるかのように振る舞います。
テーブル参照や関数呼び出しから返される値が文字列または数値である場合、その値が置換文字列として使用されます。falseやnilが返された場合、置換は行われず(つまり、元のマッチが文字列内に保持されます)。
以下は例です:
x = string.gsub("hello world", "(%w+)", "%1 %1")
-- x="hello hello world world"
x = string.gsub("hello world", "%w+", "%0 %0", 1)
-- x="hello hello world"
x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
-- x="world hello Lua from"
x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
-- x="home = /home/roberto, user = roberto"
x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
return load(s)()
end)
-- x="4+5 = 9"
local t = {name="lua", version="5.2"}
x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
-- x="lua-5.2.tar.gz"string.len (s)
文字列sを受け取り、その長さを返します。空の文字列""の長さは0です。埋め込みゼロもカウントされるため、"a\000bc\000"の長さは5になります。
string.lower (s)
文字列sを受け取り、大文字の文字をすべて小文字に変換したコピーを返します。その他の文字はそのまま残ります。大文字の定義は、現在のロケールに依存します。
string.match (s, pattern [, init])
文字列s内でpatternに最初に一致する部分を探します。見つかった場合はパターンのキャプチャを返し、見つからなければnilを返します。パターンがキャプチャを指定していない場合、マッチ全体が返されます。3番目のオプション引数initは検索の開始位置を指定し、デフォルトは1で負の値も使用できます。
string.rep (s, n [, sep])
文字列sをn回繰り返し、各コピーの間に文字列sepを挟んだ文字列を返します。sepのデフォルト値は空文字列(つまり、区切りはなし)です。
string.reverse (s)
文字列sを受け取り、その文字列を逆順にした文字列を返します。
string.sub (s, i [, j])
文字列sのインデックスiからjまでの部分文字列を返します。iとjは負の値も使用できます。jが省略された場合は-1(すなわち文字列の長さ)と見なされます。特に、string.sub(s,1,j)は長さjのsのプレフィックスを返し、string.sub(s, -i)は長さiのsのサフィックスを返します。
負のインデックスの変換後、iが1未満の場合は1に補正されます。jが文字列の長さを超える場合は、その長さに補正されます。これらの補正後、iがjより大きければ空文字列が返されます。
string.upper (s)
文字列sを受け取り、小文字の文字をすべて大文字に変換したコピーを返します。その他の文字はそのまま残ります。小文字の定義は、現在のロケールに依存します。
6.4.1 – パターン
文字クラス:
文字クラスは、特定の文字の集合を表すために使用されます。文字クラスを記述する際には、以下の組み合わせが使用できます:
x: (^$()%.[]*+-?のいずれでもないxの場合)その文字x自体を表します。.: (ドット)すべての文字を表します。%a: すべてのアルファベット文字を表します。%c: すべての制御文字を表します。%d: すべての数字を表します。%g: 空白以外のすべての印字可能文字を表します。%l: すべての小文字を表します。%p: すべての句読点文字を表します。%s: すべての空白文字を表します。%u: すべての大文字を表します。%w: すべての英数字を表します。%x: すべての16進数字を表します。%x: (xが英数字以外の文字の場合)文字x自体を表します。これは、特殊文字をエスケープする標準的な方法です。パターン内で文字そのものを表すために、%を句読点の前につけて使用できます(特殊文字以外の句読点にも適用できます)。[set]:set内のすべての文字の集合を表します。文字の範囲を指定するには、範囲の始まりと終わりの文字を-で区切ります(昇順で指定します)。また、上記で説明したクラス(例:%x)はすべて集合内で使用可能です。それ以外の文字はそのまま自身を表します。例えば、[%w_](または[_%w])はすべての英数字とアンダースコアを、[0-7]は8進数の数字を、[0-7%l%-]は8進数の数字と小文字のアルファベットと-を表します。[^set]:setの補集合を表します。setは上記と同じ解釈をされます。
一文字で表されるすべてのクラス(例:%a, %cなど)に対して、対応する大文字の文字はクラスの補集合を表します。例えば、%Sはすべての非空白文字を表します。
文字、空白、その他の文字グループの定義は、現在のロケールに依存します。特に、[a-z]のクラスは必ずしも%lと同等ではない場合があります。
パターンアイテム:
パターンアイテムは次のようになります:
- 単一の文字クラス:クラス内の任意の1文字とマッチします。
- 単一の文字クラスに
*が続く場合:クラス内の文字の0回以上の繰り返しとマッチします。この繰り返しは、常に最も長いシーケンスとマッチします。 - 単一の文字クラスに
+が続く場合:クラス内の文字の1回以上の繰り返しとマッチします。この繰り返しも常に最も長いシーケンスとマッチします。 - 単一の文字クラスに
-が続く場合:クラス内の文字の0回以上の繰り返しとマッチします。*とは異なり、常に最も短いシーケンスとマッチします。 - 単一の文字クラスに
?が続く場合:クラス内の文字の0回または1回の出現とマッチします。 %n: (nは1から9まで)n番目にキャプチャされた文字列と同じ部分文字列にマッチします(詳細は後述のキャプチャを参照)。%bxy: xとyが異なる2つの文字である場合、xで始まりyで終わる文字列にマッチします。xとyはバランスがとれている必要があります。つまり、文字列を左から右に読み、xに対して+1、yに対して-1として数えた際、yの最後がカウントが0になる最初のyである必要があります。例えば、%b()は括弧がバランスのとれた表現にマッチします。%f[set]: 境界パターンです。次の文字がsetに含まれ、前の文字がsetに含まれていない位置の空文字列にマッチします。setは前述の通りに解釈されます。対象文字列の先頭と末尾は、仮に'\0'として扱われます。
パターン:
パターンは、パターンアイテムのシーケンスです。パターンの先頭にあるキャレット^は、対象文字列の先頭でマッチを固定します。パターンの末尾にある$は、対象文字列の末尾でマッチを固定します。その他の位置にある^と$には特別な意味はなく、それ自体を表します。
キャプチャ:
パターンは括弧で囲まれたサブパターンを含むことができ、これによりキャプチャを行います。マッチが成功すると、対象文字列のキャプチャ部分が保存され、後の使用に備えられます。キャプチャは左側の括弧に基づいて番号が付けられます。例えば、パターン"(a*(.)%w(%s*))"では、文字列のうち"a*(.)%w(%s*)"にマッチする部分が最初のキャプチャとして保存され、2番目のキャプチャは.にマッチする文字で、3番目のキャプチャは%s*にマッチする部分になります。
特別なケースとして、空のキャプチャ() は現在の文字列位置(数値)をキャプチャします。例えば、文字列"flaaap"にパターン()aa()を適用すると、2つのキャプチャが生成され、それぞれ3と5が得られます。
6.5 – テーブル操作
このライブラリは、テーブル操作のための汎用的な関数を提供します。すべての関数は、table テーブルの中に格納されています。
テーブルの長さが必要な操作を行う場合、テーブルは適切なシーケンスであるか、__len メタメソッド(§3.4.6参照)を持つべきです。すべての関数は、引数として与えられたテーブル内の数値以外のキーを無視します。
パフォーマンス向上のために、これらの関数によって行われるすべてのテーブルアクセス(取得・設定)は生の(raw)アクセスで行われます。
table.concat (list [, sep [, i [, j]]])
リスト内のすべての要素が文字列または数値である場合、list[i]..sep..list[i+1]···sep..list[j] という文字列を返します。sep のデフォルト値は空文字列、i のデフォルト値は1、j のデフォルト値は #list です。i が j より大きい場合は、空文字列を返します。
table.insert (list, [pos,] value)
リストの位置 pos に要素 value を挿入し、list[pos]、list[pos+1]、···、list[#list] の要素を上にシフトします。pos のデフォルト値は #list+1 であるため、table.insert(t, x) とすると、リスト t の末尾に x を挿入します。
table.pack (···)
すべての引数をキー 1、2 などとして格納し、合計のパラメータ数をフィールド n に持つ新しいテーブルを返します。この結果として得られるテーブルは、シーケンスとは限りません。
table.remove (list [, pos])
リストの位置 pos の要素を削除し、削除された要素の値を返します。pos が 1 から #list の間の整数である場合、list[pos+1]、list[pos+2]、···、list[#list] の要素を下にシフトし、list[#list] の要素を消去します。pos は #list が0の場合は 0、または #list + 1 にすることもできます。この場合、list[pos] の要素が消去されます。
pos のデフォルト値は #list であるため、table.remove(t) はリスト t の最後の要素を削除します。
table.sort (list [, comp])
リストの要素を指定された順序で、インプレース(リストを直接変更)で list[1] から list[#list] まで並べ替えます。comp が指定された場合、2つのリスト要素を受け取り、第1要素が最終的な順序で第2要素の前に来るべきであれば true を返す関数である必要があります(したがって、ソート後に not comp(list[i+1], list[i]) が true になります)。comp が指定されない場合、標準のLua演算子 < が使用されます。
ソートアルゴリズムは安定ではありません。つまり、指定された順序で等しいとみなされる要素の相対的な位置が変更される可能性があります。
table.unpack (list [, i [, j]])
指定されたテーブルの要素を返します。この関数は以下と等価です。
return list[i], list[i+1], ···, list[j]デフォルトで、i は 1、j は #list です。
6.6 – 数学関数
このライブラリは標準Cの数学ライブラリのインターフェースです。すべての関数は、math テーブル内に格納されています。
math.abs (x)
x の絶対値を返します。
math.acos (x)
x のアークコサイン(ラジアン)を返します。
math.asin (x)
x のアークサイン(ラジアン)を返します。
math.atan (x)
x のアークタンジェント(ラジアン)を返します。
math.atan2 (y, x)
y/x のアークタンジェント(ラジアン)を返しますが、結果の象限を決定するために両方のパラメータの符号を使用します(また、x がゼロである場合も正しく処理します)。
math.ceil (x)
x 以上の最小の整数を返します。
math.cos (x)
x のコサイン(ラジアン単位)を返します。
math.cosh (x)
x のハイパーボリックコサインを返します。
math.deg (x)
角度 x(ラジアン)を度に変換して返します。
math.exp (x)
e の x 乗を返します。
math.floor (x)
x 以下の最大の整数を返します。
math.fmod (x, y)
x を y で割った余りを返しますが、商をゼロに丸めます。
math.frexp (x)
x = m * 2^e の形で m と e を返します。
math.random ([m [, n]])
この関数は、標準Cが提供する簡易疑似乱数生成関数 rand のインターフェースです。(統計的な特性についての保証はありません。)
引数なしで呼び出すと、範囲 [0, 1) の均等に分布した疑似乱数の実数を返します。整数 m が指定された場合、範囲 [1, m] の均等な疑似乱数の整数を返します。整数 m と n の両方が指定された場合、範囲 [m, n] の均等な疑似乱数の整数を返します。
math.randomseed (x)
疑似乱数生成器の「シード」として x を設定します。同じシードを設定すると、同じ数列が生成されます。
math.sin (x)
x のサイン(正弦)を返します(ラジアン単位として解釈されます)。
math.sinh (x)
x の双曲線サインを返します。
math.sqrt (x)
x の平方根を返します。(または x^0.5 として計算することも可能です。)
math.tan (x)
x のタンジェント(正接)を返します(ラジアン単位として解釈されます)。
math.tanh (x)
x の双曲線タンジェントを返します。
6.7 – ビット演算
このライブラリはビット演算を提供します。すべての関数は bit32 テーブルの中に格納されています。
特に記載がない限り、すべての関数は範囲 (-2^51, +2^51) の数値引数を受け入れます。各引数は 2^32 で割った余りで正規化され、整数に切り捨てられ(方法は未定義)、最終的な値は範囲 [0, 2^32 - 1] に収まります。なお、bit32.bnot(0) は 0xFFFFFFFF であり、これは -1 とは異なります。
bit32.arshift (x, disp)
数値 x を disp ビットだけ右にシフトして返します。disp は任意の整数で指定可能です。負の値の disp は左シフトを意味します。
このシフト操作は「算術シフト」と呼ばれます。左側の空いたビットには x の最上位ビットのコピーが埋められ、右側の空いたビットはゼロで埋められます。特に、絶対値が31を超える disp の場合は、結果がゼロまたは 0xFFFFFFFF(すべての元のビットがシフトアウトされるため)になります。
bit32.band (···)
引数のビットごとのAND(論理積)を返します。
bit32.bnot (x)
x のビットごとの否定を返します。任意の整数 x に対して、以下の等式が成り立ちます:
assert(bit32.bnot(x) == (-1 - x) % 2^32)bit32.bor (···)
引数のビットごとのOR(論理和)を返します。
bit32.btest (···)
引数のビットごとのANDがゼロ以外であるかどうかを示すブール値を返します。
bit32.bxor (···)
引数のビットごとのXOR(排他的論理和)を返します。
bit32.extract (n, field [, width])
n の指定されたビットフィールド field から field + width - 1 の範囲のビットから成る符号なし数を返します。ビットは最下位から 0 と数え、最大で31までです。アクセスされるすべてのビットは [0, 31] の範囲内である必要があります。
width のデフォルト値は 1 です。
bit32.replace (n, v, field [, width])
n のコピーに対して、指定されたビットフィールド field から field + width - 1 の範囲のビットを v の値に置き換えて返します。field および width の詳細は bit32.extract を参照してください。
bit32.lrotate (x, disp)
数値 x を disp ビット左に回転して返します。disp は任意の整数で指定可能です。
有効な disp に対して、以下の等式が成り立ちます:
assert(bit32.lrotate(x, disp) == bit32.lrotate(x, disp % 32))特に、負の disp は右回転を意味します。
bit32.lshift (x, disp)
数値 x を disp ビットだけ左にシフトして返します。disp は任意の整数で指定可能です。負の disp は右シフトを意味します。どの方向でも空いたビットはゼロで埋められます。特に、絶対値が31を超える disp の場合、結果はゼロになります(すべてのビットがシフトアウトされるため)。
正の disp に対して、以下の等式が成り立ちます:
assert(bit32.lshift(b, disp) == (b * 2^disp) % 2^32)bit32.rrotate (x, disp)
数値 x を disp ビット右に回転して返します。disp は任意の整数で指定可能です。
有効な disp に対して、以下の等式が成り立ちます:
assert(bit32.rrotate(x, disp) == bit32.rrotate(x, disp % 32))特に、負の disp は左回転を意味します。
bit32.rshift (x, disp)
数値 x を disp ビットだけ右にシフトして返します。disp は任意の整数で指定可能です。負の disp は左シフトを意味します。どの方向でも空いたビットはゼロで埋められます。特に、絶対値が31を超える disp の場合、結果はゼロになります(すべてのビットがシフトアウトされるため)。
正の disp に対して、以下の等式が成り立ちます:
assert(bit32.rshift(b, disp) == math.floor(b % 2^32 / 2^disp))このシフト操作は「論理シフト」と呼ばれます。
6.8 – 入力と出力機能
I/Oライブラリはファイル操作のための2つの異なるスタイルを提供します。1つ目のスタイルでは、暗黙のファイルディスクリプタを使用します。つまり、デフォルトの入力ファイルとデフォルトの出力ファイルを設定し、すべての入出力操作がこれらのデフォルトファイルに対して行われます。2つ目のスタイルでは、明示的なファイルディスクリプタを使用します。
暗黙のファイルディスクリプタを使用する場合、すべての操作は io テーブルによって提供されます。明示的なファイルディスクリプタを使用する場合、io.open はファイルディスクリプタを返し、すべての操作はそのファイルディスクリプタのメソッドとして提供されます。
io テーブルには、C言語でおなじみの3つの事前定義されたファイルディスクリプタも提供されています:io.stdin、io.stdout、および io.stderr。I/Oライブラリはこれらのファイルを閉じません。
特に記載がない限り、すべてのI/O関数は失敗時に nil を返し(エラーメッセージを第2戻り値として、システム依存のエラーコードを第3戻り値として返します)、成功時には nil 以外の値を返します。非Posixシステムでは、エラーメッセージとエラーコードの計算がスレッドセーフでない可能性があります。これは、グローバルなC変数 errno に依存しているためです。
io.close ([file])
file:close() と同等です。ファイルを指定しない場合、デフォルトの出力ファイルを閉じます。
io.flush ()
io.output():flush() と同等です。
io.input ([file])
ファイル名を指定すると、その名前のファイルをテキストモードで開き、そのハンドルをデフォルトの入力ファイルとして設定します。ファイルハンドルを指定した場合、そのファイルハンドルをデフォルトの入力ファイルとして設定します。引数なしで呼び出すと、現在のデフォルト入力ファイルを返します。
エラーが発生した場合、この関数はエラーを発生させ、エラーコードを返しません。
io.lines ([filename ···])
指定されたファイル名を読み取りモードで開き、開かれたファイルに対して file:lines(···) のように動作するイテレータ関数を返します。イテレータ関数がファイルの終端を検出すると、nil を返してループを終了し、自動的にファイルを閉じます。
ファイル名なしで io.lines() を呼び出すと、io.input():lines() と等価になり、デフォルトの入力ファイルの行を繰り返し処理します。この場合、ループが終了してもファイルは閉じられません。
エラーが発生した場合、この関数はエラーを発生させ、エラーコードを返しません。
io.open (filename [, mode])
指定された mode の文字列に従ってファイルを開きます。新しいファイルハンドルを返し、エラーが発生した場合は nil とエラーメッセージを返します。
mode の文字列は以下のいずれかです:
"r": 読み込みモード(デフォルト)"w": 書き込みモード"a": 追加モード"r+": 更新モード(既存のデータは保持される)"w+": 更新モード(既存のデータは消去される)"a+": 追加更新モード(既存のデータは保持され、書き込みはファイルの末尾でのみ行われる)
mode 文字列の末尾に 'b' を付けることで、バイナリモードでファイルを開くことが必要なシステムもあります。
io.output ([file])
io.input と似ていますが、デフォルトの出力ファイルに対して動作します。
io.popen (prog [, mode])
この関数はシステム依存であり、すべてのプラットフォームで利用可能とは限りません。
prog というプログラムを別プロセスで開始し、モードが "r"(デフォルト)の場合はそのプログラムからデータを読み取るため、モードが "w" の場合はそのプログラムにデータを書き込むためのファイルハンドルを返します。
io.read (···)
io.input():read(···) と同等です。
io.tmpfile ()
一時ファイルのハンドルを返します。このファイルは更新モードで開かれ、プログラムが終了すると自動的に削除されます。
io.type (obj)
obj が有効なファイルハンドルかどうかを確認します。obj が開いたファイルハンドルの場合は "file" を、閉じたファイルハンドルの場合は "closed file" を、ファイルハンドルでない場合は nil を返します。
io.write (···)
io.output():write(···) と同等です。
file:close ()
ファイルを閉じます。ファイルハンドルはガベージコレクション時に自動的に閉じられますが、これがいつ起こるかは予測できません。
io.popen で作成されたファイルハンドルを閉じる場合、file:close は os.execute と同じ値を返します。
file:flush ()
書き込まれたデータをファイルに保存します。
file:lines (···)
イテレータ関数を返します。この関数を呼び出すたびに、指定されたフォーマットに従ってファイルからデータを読み取ります。フォーマットが指定されていない場合、デフォルトで "*l" が使用されます。例えば、
for c in file:lines(1) do body endと記述すると、現在の位置からファイル内のすべての文字に対して繰り返し処理が行われます。この関数は io.lines とは異なり、ループが終了してもファイルを閉じません。
エラーが発生した場合、この関数はエラーを発生させ、エラーコードは返しません。
file:read (···)
指定されたフォーマットに従ってファイルを読み取ります。各フォーマットに応じて、読み取られた文字列(または数値)を返します。指定されたフォーマットでデータを読み取れない場合は nil を返します。フォーマットを指定せずに呼び出した場合、次の行を読み取るデフォルトフォーマットが使用されます(下記参照)。
使用可能なフォーマットは次のとおりです:
"*n": 数値を読み取ります。このフォーマットのみ数値を返し、文字列を返しません。"*a": 現在の位置からファイル全体を読み取ります。ファイルの終端では空文字列を返します。"*l": 次の行を読み取り、行末を除いて返します。ファイルの終端ではnilを返します(デフォルトフォーマット)。"*L": 次の行を読み取り、行末も含めて返します。ファイルの終端ではnilを返します。- 数値: 指定したバイト数までの文字列を読み取ります。ファイルの終端では
nilを返します。数値がゼロの場合、何も読み取らず空文字列を返しますが、ファイルの終端ではnilを返します。
file:seek ([whence [, offset]])
ファイルの位置を設定または取得します。ファイルの先頭からのバイト数で指定された位置に移動し、whence で指定された基準から offset を加えた位置に設定します。whence の指定方法は次のとおりです:
"set": 基準はファイルの先頭(位置 0)"cur": 基準は現在の位置"end": 基準はファイルの終端
成功時には、ファイルの先頭からの最終位置をバイト数で返します。失敗した場合は nil とエラー内容の文字列を返します。
whence のデフォルト値は "cur"、offset のデフォルト値は 0 です。そのため、file:seek() を呼び出すと現在のファイル位置を取得し、位置を変更せずに返します。また、file:seek("set") は位置をファイルの先頭に設定し、0 を返します。file:seek("end") は位置をファイルの終端に設定し、そのファイルサイズを返します。
file:setvbuf (mode [, size])
出力ファイルのバッファリングモードを設定します。利用可能なモードは以下の3つです:
"no": バッファリングなし;出力操作の結果が即時に反映されます。"full": 完全バッファリング;バッファが満杯になるか明示的にファイルをフラッシュする(io.flush参照)まで出力されません。"line": 行単位のバッファリング;改行が出力されるか、端末デバイスなどの特殊ファイルからの入力があるまで出力をバッファリングします。
後の2つのモードでは、バッファサイズをバイト単位で size に指定できます。デフォルトでは適切なサイズが自動で設定されます。
file:write (···)
各引数の値をファイルに書き込みます。引数は文字列または数値である必要があります。
成功した場合、この関数はファイルを返します。失敗した場合、nil とエラー内容の文字列を返します。
6.9 – オペレーティングシステム機能
このライブラリは os テーブルを通じて実装されています。
os.clock ()
プログラムが使用したCPU時間の概算値を秒単位で返します。
os.date ([format [, time]])
指定された format に従って、日付と時刻を含む文字列またはテーブルを返します。
time 引数が指定されている場合はその時間がフォーマットされます(この値の詳細については os.time 関数を参照)。指定がない場合、現在の時刻がフォーマットされます。
format が '!' で始まる場合、日付は協定世界時(UTC)でフォーマットされます。このオプション文字の後に format が文字列 "*t" であれば、以下のフィールドを持つテーブルが返されます:year(4桁の年)、month(1–12)、day(1–31)、hour(0–23)、min(0–59)、sec(0–61)、wday(曜日、日曜日が1)、yday(年の日付)、isdst(夏時間フラグ、ブール値)。この最後のフィールドは、情報が利用できない場合は省略されることがあります。
format が "*t" でない場合は、ISO C関数 strftime のルールに従って文字列として日付が返されます。
引数なしで呼び出すと、ホストシステムと現在のロケールに依存した適切な日付と時刻の表現を返します(つまり、os.date() は os.date("%c") と等価です)。
非Posixシステムでは、C関数 gmtime および localtime に依存しているため、この関数はスレッドセーフではない可能性があります。
os.difftime (t2, t1)
時刻 t1 から t2 までの秒数を返します。POSIX、Windows、および他の一部のシステムでは、この値はちょうど t2 - t1 に等しくなります。
os.execute ([command])
ISO C関数 system と等価です。command をオペレーティングシステムのシェルで実行するように渡します。最初の結果は、コマンドが正常終了した場合は true、それ以外は nil です。この最初の結果の後に、以下のように文字列と数値を返します:
"exit": コマンドは正常に終了しました。この後の数値はコマンドの終了ステータスです。"signal": コマンドはシグナルによって終了しました。この後の数値はコマンドを終了させたシグナルの番号です。
コマンドなしで呼び出すと、os.execute はシェルが利用可能かどうかを示すブール値を返します。
os.exit ([code [, close]])
ホストプログラムを終了するためにISO C関数 exit を呼び出します。code が true の場合、終了ステータスは EXIT_SUCCESS になります。code が false の場合、終了ステータスは EXIT_FAILURE になります。code が数値である場合、終了ステータスはその数値になります。code のデフォルト値は true です。
オプションの第2引数 close が true の場合、Luaステートを閉じてから終了します。
os.getenv (varname)
環境変数 varname の値を返します。変数が定義されていない場合は nil を返します。
os.remove (filename)
指定した名前のファイル(POSIXシステムでは空のディレクトリも可)を削除します。失敗した場合は nil とエラー内容の文字列、およびエラーコードを返します。
os.rename (oldname, newname)
ファイルまたはディレクトリ名を oldname から newname に変更します。失敗した場合は nil とエラー内容の文字列、およびエラーコードを返します。
os.setlocale (locale [, category])
プログラムの現在のロケールを設定します。locale はシステム依存の文字列で、ロケールを指定します。category はオプションの文字列で、変更するカテゴリを示します:"all"、"collate"、"ctype"、"monetary"、"numeric"、または "time"。デフォルトのカテゴリは "all" です。この関数は新しいロケールの名前を返し、要求を満たせない場合は nil を返します。
locale が空文字列の場合、現在のロケールは実装定義のネイティブロケールに設定されます。locale が文字列 "C" の場合、現在のロケールは標準のCロケールに設定されます。
最初の引数として nil を指定して呼び出した場合、この関数は指定されたカテゴリの現在のロケールの名前だけを返します。
C関数 setlocale に依存しているため、この関数はスレッドセーフではない可能性があります。
os.time ([table])
引数なしで呼び出すと、現在の時刻を返します。引数としてテーブルを渡すと、指定された日付と時刻を表す時間を返します。このテーブルには year、month、および day フィールドが必要で、hour(デフォルトは 12)、min(デフォルトは 0)、sec(デフォルトは 0)、および isdst(デフォルトは nil)のフィールドを含めることができます。これらのフィールドの詳細については、os.date 関数を参照してください。
返される値は数値であり、その意味はシステムによって異なります。POSIX、Windows、その他一部のシステムでは、この数値は特定の開始時刻(「エポック」)からの秒数を示します。他のシステムでは、意味は指定されておらず、time によって返された数値は os.date や os.difftime の引数としてのみ使用できます。
os.tmpname ()
一時ファイルとして使用できるファイル名の文字列を返します。このファイルは使用前に明示的に開く必要があり、不要になったら明示的に削除する必要があります。
POSIXシステムでは、この関数はその名前のファイルも作成します。これは、名前を取得してからファイルを作成する間に他人が間違った権限でファイルを作成するリスクを避けるためです。それでもファイルを開いて使用し、不要になったら削除する必要があります(使用しない場合も削除が必要です)。
可能であれば、プログラムの終了時に自動的にファイルを削除する io.tmpfile を使用することを推奨します。
6.10 – デバッグライブラリ
このライブラリは、Luaプログラムにデバッグインターフェース(§4.9)の機能を提供します。このライブラリを使用する際には注意が必要です。いくつかの関数は、Luaコードの基本的な前提(例:関数のローカル変数は外部からアクセスできない、ユーザーデータのメタテーブルはLuaコードで変更できない、Luaプログラムがクラッシュしない等)を破るため、安全なコードであっても危険にさらされる可能性があります。さらに、このライブラリの一部の関数は遅い場合があります。
このライブラリのすべての関数は debug テーブル内に提供されています。スレッドを操作する関数は、オプションの最初の引数として操作対象のスレッドを指定できます。デフォルトは常に現在のスレッドです。
debug.debug ()
対話モードに入り、ユーザーが入力した各文字列を実行します。簡単なコマンドや他のデバッグ機能を使って、グローバル変数やローカル変数を調査したり、その値を変更したり、式を評価したりできます。「cont」のみを含む行を入力すると、この関数が終了し、呼び出し元の実行が続行されます。
debug.debug のコマンドは任意の関数内にレキシカルにネストされていないため、直接ローカル変数にはアクセスできません。
debug.gethook ([thread])
スレッドの現在のフック設定を3つの値として返します:現在のフック関数、現在のフックマスク、および現在のフックカウント(debug.sethook 関数によって設定されたもの)。
debug.getinfo ([thread,] f [, what])
関数についての情報を含むテーブルを返します。f には関数を直接渡すことも、数値を渡して呼び出しスタック内の指定レベルの関数を指定することもできます。レベル0は現在の関数(getinfo 自体)で、レベル1は getinfo を呼び出した関数です(ただし、スタックにカウントされない末尾呼び出しは例外です)。f が有効な関数の数を超える場合、getinfo は nil を返します。
返されるテーブルには lua_getinfo によって返されるすべてのフィールドが含まれ、文字列 what でどのフィールドに情報を格納するかを指定します。what のデフォルトは、利用可能なすべての情報(有効な行のテーブルを除く)を取得することです。オプション 'f' が存在すると、関数自体を格納する func というフィールドが追加されます。オプション 'L' が存在すると、有効な行のテーブルを含む activelines フィールドが追加されます。
例えば、debug.getinfo(1,"n").name は、現在の関数の名前(見つかる場合)を含むテーブルを返し、debug.getinfo(print) は print 関数についての利用可能なすべての情報を含むテーブルを返します。
debug.getlocal ([thread,] f, local)
スタック内のレベル f の関数のローカル変数のインデックス local に対応する名前と値を返します。この関数は、明示的なローカル変数だけでなく、パラメータや一時変数などもアクセスします。
最初のパラメータやローカル変数はインデックス1を持ち、順に最後の有効な変数まで続きます。負のインデックスは可変長引数(vararg)のパラメータを指し、-1 が最初の可変長引数になります。指定したインデックスに変数がない場合は nil を返し、範囲外のレベルで呼び出すとエラーが発生します(有効なレベルかどうかは debug.getinfo で確認できます)。
変数名が '('(開き括弧)で始まる場合、内部変数(ループ制御変数、一時変数、可変長引数、C関数のローカル変数)を示します。
パラメータ f に関数を指定することもできます。その場合、getlocal は関数のパラメータの名前のみを返します。
debug.getmetatable (value)
指定された値のメタテーブルを返します。メタテーブルがない場合は nil を返します。
debug.getregistry ()
レジストリテーブルを返します(§4.5参照)。
debug.getupvalue (f, up)
関数 f のアップバリューのインデックス up に対応する名前と値を返します。指定したインデックスにアップバリューがない場合は nil を返します。
debug.getuservalue (u)
指定した u に関連付けられたLuaの値を返します。u がユーザーデータでない場合は nil を返します。
debug.sethook ([thread,] hook, mask [, count])
指定された関数をフックとして設定します。文字列 mask と数値 count はフックが呼び出されるタイミングを指定します。mask 文字列は次の文字の組み合わせで構成され、それぞれの意味は以下の通りです:
'c': Luaが関数を呼び出すたびにフックが呼び出されます。'r': Luaが関数から戻るたびにフックが呼び出されます。'l': Luaが新しいコード行に入るたびにフックが呼び出されます。
さらに、count が0以外の場合、指定された命令数ごとにフックが呼び出されます。
引数なしで呼び出すと、debug.sethook はフックを無効にします。
フックが呼び出されると、最初のパラメータには呼び出しを引き起こしたイベントを表す文字列が渡されます("call"、"tail call"、"return"、"line"、"count" のいずれか)。行イベントの場合、フックの2番目のパラメータとして新しい行番号も渡されます。フック内では、getinfo をレベル2で呼び出すことで実行中の関数に関する情報を取得できます(レベル0は getinfo 関数、レベル1はフック関数です)。
debug.setlocal ([thread,] level, local, value)
スタック内の指定レベル level の関数のローカル変数インデックス local に value を代入します。指定したインデックスにローカル変数がない場合は nil を返し、範囲外のレベルで呼び出すとエラーが発生します(有効なレベルかどうかは getinfo で確認できます)。ローカル変数が存在する場合、その変数の名前を返します。
変数インデックスと名前の詳細については、debug.getlocal を参照してください。
debug.setmetatable (value, table)
指定された値のメタテーブルを table に設定します(table は nil にすることも可能です)。value を返します。
debug.setupvalue (f, up, value)
関数 f のアップバリューインデックス up に value を代入します。指定したインデックスにアップバリューがない場合は nil を返します。それ以外の場合は、アップバリューの名前を返します。
debug.setuservalue (udata, value)
指定されたユーザーデータ udata に関連付けられたLuaの値を value に設定します。value はテーブルまたは nil である必要があり、udata は完全なユーザーデータである必要があります。
udata を返します。
debug.traceback ([thread,] [message [, level]])
message が指定されており、それが文字列でも nil でもない場合、この関数は message をそのまま返します。それ以外の場合、コールスタックのトレースバックを含む文字列を返します。オプションで message 文字列をトレースバックの先頭に追加できます。オプションの level 数値はトレースバックを開始するレベルを指定し、デフォルトは1(traceback を呼び出した関数)です。
debug.upvalueid (f, n)
指定された関数の n 番目のアップバリューに対する一意の識別子(ライトユーザーデータとして)を返します。
この識別子により、異なるクロージャがアップバリューを共有しているかを確認できます。同じアップバリュー(つまり、同じ外部ローカル変数)を参照するLuaクロージャは、そのアップバリューインデックスに対して同一のIDを返します。
debug.upvaluejoin (f1, n1, f2, n2)
Luaクロージャ f1 の n1 番目のアップバリューを、Luaクロージャ f2 の n2 番目のアップバリューに関連付けます。
7 – Lua スタンドアロン
LuaはホストCプログラムに埋め込む拡張言語として設計されていますが、スタンドアロンの言語としてもよく使用されます。標準配布には lua と呼ばれるスタンドアロン言語としてのインタプリタが含まれています。スタンドアロンインタプリタにはデバッグライブラリを含むすべての標準ライブラリが組み込まれています。使用法は次の通りです:
lua [オプション] [スクリプト [引数]]オプションは以下の通りです:
-e stat: 文字列statを実行します。-l mod:modを "require" します。-i: スクリプト実行後に対話モードに入ります。-v: バージョン情報を表示します。-E: 環境変数を無視します。--: オプションの処理を停止します。-: 標準入力(stdin)をファイルとして実行し、オプションの処理を停止します。
オプションの処理が完了すると、lua は指定されたスクリプトを実行し、指定された引数を文字列として渡します。引数なしで呼び出された場合、標準入力が端末の場合は lua -v -i として動作し、それ以外の場合は lua - として動作します。
オプション -E が指定されていない場合、インタプリタは引数を処理する前に、環境変数 LUA_INIT_5_2(または未定義の場合は LUA_INIT)を確認します。変数の内容が @filename という形式であれば、lua はそのファイルを実行します。それ以外の場合、文字列自体を実行します。
-E オプションを指定すると、LUA_INIT を無視するだけでなく、LUA_PATH と LUA_CPATH の値も無視し、package.path と package.cpath に luaconf.h に定義されたデフォルトのパスを設定します。
-i と -E 以外のオプションは順番に処理されます。例えば、次のように呼び出すと:
$ lua -e'a=1' -e 'print(a)' script.lua最初に a に1を設定し、その後 a の値を表示し、最後に引数なしでファイル script.lua を実行します。(ここで $ はシェルプロンプトです。あなたのプロンプトは異なるかもしれません。)
スクリプトを実行する前に、lua はコマンドラインのすべての引数を arg というグローバルテーブルに収集します。スクリプト名はインデックス 0 に格納され、スクリプト名の後の最初の引数がインデックス 1 に、それ以降も同様に格納されます。スクリプト名より前の引数(インタプリタ名とオプション)は負のインデックスに格納されます。例えば、次の呼び出しでは:
$ lua -la b.lua t1 t2インタプリタは最初にファイル a.lua を実行し、その後テーブル arg を次のように作成します:
arg = { [-2] = "lua", [-1] = "-la",
[0] = "b.lua",
[1] = "t1", [2] = "t2" }最後に b.lua を実行します。スクリプトは arg[1]、arg[2]、... のように引数を受け取り、... という可変長引数表現を使用してこれらの引数にアクセスすることもできます。
対話モードでは、不完全なステートメントを入力すると、インタプリタは別のプロンプトを表示して完了を待機します。
スクリプト内で保護されていないエラーが発生した場合、インタプリタは標準エラーストリームにエラーを報告します。エラーオブジェクトが文字列の場合、スタックトレースが追加されます。それ以外の場合、エラーオブジェクトに __tostring メタメソッドがある場合、インタプリタはこのメタメソッドを呼び出して最終的なメッセージを生成します。エラーオブジェクトが nil の場合、インタプリタはエラーを報告しません。
正常に終了する場合、インタプリタはメインのLua状態を閉じます(lua_close 参照)。スクリプトは os.exit を呼び出して終了することで、この手順を回避できます。
LuaをUnixシステムのスクリプトインタプリタとして使用できるように、スタンドアロンインタプリタはチャンクの最初の行が # で始まる場合、この行をスキップします。このため、Luaスクリプトを次のように chmod +x と #! を使用して実行可能プログラムにすることができます。
#!/usr/local/bin/lua(もちろん、Luaインタプリタの場所はマシンによって異なる場合があります。もし lua が PATH に含まれている場合、次のようにするとより移植性が高くなります。)
#!/usr/bin/env lua8 – 前バージョンとの非互換性
ここでは、Lua 5.1 から Lua 5.2 にプログラムを移行する際に発生する可能性がある非互換性について説明します。Luaを適切なオプションでコンパイルすることで一部の非互換性を回避できます(luaconf.h ファイルを参照)。ただし、これらの互換性オプションは次のバージョンのLuaでは削除される予定です。同様に、Lua 5.1 で非推奨とされていた機能は Lua 5.2 で削除されました。
8.1 – 言語の変更点
- 環境(environment)の概念が変更されました。環境を持つのはLua関数のみです。Lua関数の環境を設定するには、変数
_ENVまたは関数loadを使用します。 - C関数は環境を持ちません。複数のC関数間で共有状態を維持する場合、共有テーブルをアップバリューとして使用してください(Cライブラリを開くときに、すべての関数が共通のアップバリューを共有するよう
luaL_setfuncsを使用できます)。 - ユーザーデータの「環境」を操作するには、
lua_getuservalueおよびlua_setuservalueを使用します(ユーザーデータの環境は「ユーザー値」と呼ばれるようになりました)。 - Lua識別子にロケール依存の文字を使用できなくなりました。
- ガベージコレクタでステップまたは完全なコレクションを行っても、停止しているガベージコレクタは再起動しません。
- 弱キーを持つ弱テーブルは、エフェメロンテーブルのように動作します。
- デバッグフックでの
tail returnイベントが削除され、代わりに新しいイベントtail callが追加されました。これにより、デバッガーは対応する戻りイベントがないことを認識できます。 - 関数値の等価性が変更されました。現在、関数の定義によって新しい値が作成されない場合があり、観察可能な違いがなければ以前の値を再利用することがあります。
8.2 – ライブラリの変更点
module関数は非推奨になりました。通常のLuaコードでモジュールを設定できます。モジュールはグローバル変数を設定しないことが推奨されます。setfenvおよびgetfenv関数が削除されました(環境の変更による)。math.log10関数は非推奨になりました。代わりにmath.logを2つ目の引数として10を指定して使用してください。loadstring関数は非推奨になりました。代わりにloadを使用します。loadは文字列引数を受け取り、loadstringと完全に同等です。table.maxn関数は非推奨になりました。本当に必要であれば、Luaで同等の機能を実装してください。os.execute関数は、コマンドが正常に終了した場合にtrueを返し、それ以外の場合はnilとエラー情報を返すようになりました。unpack関数はテーブルライブラリに移動されたため、table.unpackとして呼び出す必要があります。- パターンにおける文字クラス
%zは非推奨になりました。現在、パターンには'\0'を通常の文字として含めることができます。 package.loadersテーブルはpackage.searchersに名前が変更されました。- Luaはバイトコードの検証を行わなくなりました。そのため、コードを読み込むすべての関数(
loadおよびloadfile)は、信頼できないバイナリデータを読み込む場合に潜在的に安全ではありません(実際、以前のバージョンでも検証アルゴリズムに欠陥があり安全ではありませんでした)。疑わしい場合は、これらの関数のmode引数を使用して、テキストチャンクの読み込みに制限することを推奨します。 - 標準パスは公式ディストリビューションのバージョン間で変更される可能性があります。
8.3 – APIの変更点
- 疑似インデックス
LUA_GLOBALSINDEXが削除されました。グローバル環境はレジストリから取得する必要があります(§4.5 参照)。 - 疑似インデックス
LUA_ENVIRONINDEXおよび関数lua_getfenv/lua_setfenvが削除されました(C関数は環境を持たないため)。 luaL_register関数は非推奨になりました。グローバル変数を作成しないよう、luaL_setfuncsを使用してください(モジュールはもはやグローバル変数を設定しないことが推奨されています)。- メモリ割り当て関数の
osize引数は、新しいブロックを作成する場合(つまりptrがNULLの場合)ゼロではない可能性があります。新しいブロックかどうかを確認するには、ptr == NULLのテストのみを使用してください。 - ユーザーデータのファイナライザ(
__gcメタメソッド)は、作成された順ではなく、ファイナライズとしてマークされた順に逆順で呼び出されます(§2.5.1 参照)。ほとんどのユーザーデータは作成直後にファイナライズとしてマークされます。また、メタテーブルに__gcフィールドが設定されていない場合、後から設定してもファイナライザは呼び出されません。 luaL_typerrorが削除されました。必要に応じて独自のバージョンを実装してください。lua_cpcall関数は非推奨になりました。lua_pushcfunctionで関数をプッシュし、lua_pcallで呼び出すだけで同等の動作を実現できます。lua_equalおよびlua_lessthan関数は非推奨になりました。代わりに、新しいlua_compareを適切なオプションで使用してください。lua_objlen関数はlua_rawlenに名前が変更されました。lua_load関数には追加のパラメータmodeが追加されました。以前の動作をシミュレートするにはNULLを渡してください。lua_resume関数には追加のパラメータfromが追加されました。呼び出し元のスレッドかNULLを渡してください。
9 – Luaの完全な構文
以下は、Luaの完全な構文を拡張BNFで表したものです。(演算子の優先順位は記述されていません。)
chunk ::= block
block ::= {stat} [retstat]
stat ::= ‘;’ |
varlist ‘=’ explist |
functioncall |
label |
break |
goto Name |
do block end |
while exp do block end |
repeat block until exp |
if exp then block {elseif exp then block} [else block] end |
for Name ‘=’ exp ‘,’ exp [‘,’ exp] do block end |
for namelist in explist do block end |
function funcname funcbody |
local function Name funcbody |
local namelist [‘=’ explist]
retstat ::= return [explist] [‘;’]
label ::= ‘::’ Name ‘::’
funcname ::= Name {‘.’ Name} [‘:’ Name]
varlist ::= var {‘,’ var}
var ::= Name | prefixexp ‘[’ exp ‘]’ | prefixexp ‘.’ Name
namelist ::= Name {‘,’ Name}
explist ::= exp {‘,’ exp}
exp ::= nil | false | true | Number | String | ‘...’ | functiondef |
prefixexp | tableconstructor | exp binop exp | unop exp
prefixexp ::= var | functioncall | ‘(’ exp ‘)’
functioncall ::= prefixexp args | prefixexp ‘:’ Name args
args ::= ‘(’ [explist] ‘)’ | tableconstructor | String
functiondef ::= function funcbody
funcbody ::= ‘(’ [parlist] ‘)’ block end
parlist ::= namelist [‘,’ ‘...’] | ‘...’
tableconstructor ::= ‘{’ [fieldlist] ‘}’
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= ‘[’ exp ‘]’ ‘=’ exp | Name ‘=’ exp | exp
fieldsep ::= ‘,’ | ‘;’
binop ::= ‘+’ | ‘-’ | ‘*’ | ‘/’ | ‘^’ | ‘%’ | ‘..’ |
‘<’ | ‘<=’ | ‘>’ | ‘>=’ | ‘==’ | ‘~=’ |
and | or
unop ::= ‘-’ | not | ‘#’