Copyright © 2003 Tecgraf, PUC-Rio. All rights reserved.
Copyright © 2003 Tecgraf, PUC-Rio. All rights reserved.
この文書は、
Lua 5.0 Reference manual
を原著者に無断で日本語に訳した、非公式の Lua 5.0 リファレンスマニュアルである。
1 - 概要
Luaは拡張プログラミング言語である。 データ記述機能を持ち、汎用の手続き型プログラミングをサポートするようデザインされた。 オブジェクト指向プログラミング、関数型プログラミング、データ駆動型プログラミングもサポートしている。 Luaは、パワフルで軽いコンフィギュレーション言語としての意図もあり、 コンフィギュレーションが必要なあらゆるプログラムに使うことができる。 Luaは クリーンな C (つまり、ANSI C と C++ の共通のサブセット) で書かれ、ライブラリとして実装されている。
拡張言語であるため、Luaは「メイン」プログラムを持たない。 ホストクライアント (エンベッディングプログラム、あるいは単にホスト とも呼ぶ) に 組み込まれて 動くだけである。 このホストプログラムは、Luaコードを実行する関数を呼び出したり、Luaの変数を読み書きしたり、Luaから呼ばれるCの関数を登録したりできる。 Cの関数を使ってカスタマイズすることで、共通の構文を持つプログラミング言語で様々な領域を広範囲にカバーすることができる。
Luaのディストリビューションにはスタンドアロンのホストプログラム lua
が含まれている。
これはLuaのライブラリを使った完全なLuaインタプリタである。
Luaはフリーソフトウェアであり、著作権表示にも書かれているように、いかなる保証もなくあるがまま提供される。
このマニュアルに記述されている実装はLuaの公式ウェブサイト www.lua.org
で提供されている。
他のすべてのリファレンスマニュアルと同様、この文書はあちこちが無味乾燥である。 Luaのデザインの背後にある決定についての議論は以下の文書を参照。 これらはLuaのウェブサイトで手に入る。
Luaはポルトガル語で「月」を意味し、ルアと発音する。
このセクションでは、Luaの字句、構文、意味論について記述する。 言い換えると、このセクションでは、どういったトークンが有効か、それらをどう組み合わせられるのか、そしてその組み合わせは何を意味するのかについて記述している。
言語構造は一般的な拡張BNF記法を使って説明する。
{a} は a の0回以上の繰り返し、[a] は a が省略可能であることを表す。
非終端記号は italic で表され、キーワードは bold、他の終端記号はシングルクォートで囲まれた type writer
フォントで表現される。
Luaの 識別子 は、文字、数字、アンダースコアを組み合わせた文字列である。 ただし数字で始まってはならない。 これは多くの言語の識別子の定義に一致する。 「文字」の定義は現在のロケールに依存する。 現在のロケールでアルファベットとみなされるいかなる文字も、識別子に使える。
以下の キーワード は予約されており、識別子としては使えない。
and break do else elseif end false for function if in local nil not or repeat return then true until while
Lua は大文字小文字を区別する言語である。
and
は予約語だが、And
と AND
は、2つの、異なった、有効な識別子である。
慣習的に、アンダースコアと大文字で始まる識別子 (例えば _VERSION
) は、
Luaが使う内部変数として予約されている。
以下の文字列は、その他のトークンである。
+ - * / ^ = ~= <= >= < > == ( ) { } [ ] ; : , . .. ...
文字列リテラル は対になるシングルクォートかダブルクォートで囲まれ、 以下の C のようなエスケープシーケンスを含むことができる。
\a
--- ベル
\b
--- バックスペース
\f
--- 改ページ
\n
--- 改行
\r
--- 復帰
\t
--- 水平タブ
\v
--- 垂直タブ
\\
--- バックスラッシュ (円記号)
\"
--- 引用符
\'
--- アポストロフィ
\[
--- 開き角カッコ
\]
--- 閉じ角カッコ
上記に加えて、
`\
改行´
(バックスラッシュに本物の改行が続いたもの)
を記述して文字列中に改行を含めることができる。
さらに `\
ddd´ (dddは3桁の10進数) というエスケープシーケンスを使って
文字列中の文字をそのコード値で指定することもできる。
Luaの文字列は `\0
´ で表されるゼロを含み、いかなる8ビット値も含むことができる。
文字列リテラルは対になる二重の角カッコ [[
· · · ]]
で表すこともできる。
この角カッコ形式のリテラルは、複数行に渡って記述したり、
[[
· · · ]]
の対を入れ子にすることができ、
エスケープシーケンスは一切解釈されない。
便利なように、`[[
´ のすぐ後に改行が続いたときは、その改行は文字列に含まれない。
例えば、ASCII (つまり `a
´ が97、改行が10、`1
´ が49であるような文字コード)
が使われているシステムでは、
以下の4つのリテラルは同じ文字列を表現している。
(1) "alo\n123\"" (2) '\97lo\10\04923"' (3) [[alo 123"]] (4) [[ alo 123"]]
数値定数 には省略可能な小数部と省略可能な指数部を書くことができる。 有効な数値定数の例を挙げると
3 3.0 3.1416 314.16e-2 0.31416E1
コメント は文字列の外ならどこでも、二つのハイフン (--
) で始めることができる。
もし --
の直後に [[
以外のテキストがあれば、そのコメントは 短いコメント であり、行末まで続く。
そうでなければ、それは 長いコメント であり、対応する ]]
まで続く。
長いコメントは複数行に渡って書くことができ、
[[
· · · ]]
の対を入れ子にできる。
もし #
で始まっていれば、チャンクの最初の行はスキップされる。
この機能はLuaをUnixシステムでスクリプトインタプリタとして使うのに便利である
(6を参照)。
Luaは 動的な型の言語 である。 つまり、変数は型を持たず、値が型を持つ。 型定義の構文はない。 すべての値は自分自身で型を保持している。
Luaには8つの基本型がある。
nil、ブーリアン、数値、文字列、関数、ユーザーデータ, スレッド、テーブル である。
nil は nil 値の型である。その主な性質は他のいかなる値とも異なることであり、通常、役に立つ値がないことを表す。
ブーリアン は false と true の値を持つ型である。
Luaでは、nil と false は共に条件判断で偽となり、他の値は真となる。
数値 は実数 (double) を表現する。
(しかし数値を表す内部表現としてfloatやlongなど他の型を使うように簡単に作り変えることもできる。)
文字列 は文字の配列を表現する。
Luaは8ビットクリーンであり、
文字列にはゼロ ('\0'
) を含むいかなる8ビット文字も含むことができる (2.1を参照)。
Luaでは関数は ファーストクラス である。 つまり、関数は変数に格納でき、他の関数の引数に渡すことができ、戻り値として返すことができる。 LuaはLuaで書かれた関数もCで書かれた関数も呼べる。
ユーザーデータ は任意のCのデータをLuaの変数に格納するために用意された。 この型は生のメモリブロックに相当し、代入と等価比較を除いて、Luaでは演算が定義されていない。 しかしながら、メタテーブル を用いることで、 プログラマはユーザーデータに対する演算を定義することができる (2.8 を参照)。 ユーザーデータはLua内で作ったり変更することはできず、CのAPIを通してのみ可能である。 これは完全にホストプログラムに所有されたデータであることを保証する。
スレッド は実行されているそれぞれのスレッドを表現し、コルーチンを実装するために使われる。
テーブル は連想配列である。
すなわち数値だけでなく任意の値 (nil を除く) をキーにできる配列である。
また、テーブルは 異種混合 できる。
つまりあらゆる型の値 (nil を除く) を持つことができる。
テーブルはLuaの唯一のデータ構造であり、
普通の配列の他、記号表、集合、レコード、グラフ、ツリーなどを表現するために使われる。
レコードを表現するときは、フィールド名をインデックスとして使う。
このための a.name
という表現が a["name"]
のシンタックスシュガーとして用意されている。
また、Luaでテーブルを作るための便利な表現がいくつかある (2.5.6 を参照)。
インデックスと同様、テーブルフィールドの値には任意の型 (nil を除く) を格納できる。 特に、関数がファーストクラスであるため、テーブルフィールドは関数を格納することができる。 そのためテーブルは メソッド を持つことができる (2.5.8 を参照)。
テーブル、関数、ユーザーデータの値は オブジェクト である。 変数はこれらの実際の値は持たず、それらを 参照 しているだけである。 代入、引数渡し、関数の戻り値は、常に値への参照を扱い、値のコピーは行われない。
ライブラリ関数 type
は与えられた値の型を表す文字列を返す
(5.1 を参照)。
Luaは文字列と数値を実行時に自動的に変換する。
すべての数学演算は、文字列に適用されると、一般的なルールに基づいてその文字列を数値に変換しようとする。
逆に、文字列が期待されるところで数値が使れると、その数値は一般的な形式の文字列に変換される。
数値が文字列に変換される方法を完璧にコントロールする場合は、
文字列ライブラリの format
関数を使う (5.3 を参照)。
変数は値を格納する場所である。 Luaには、グローバル変数、ローカル変数、テーブルフィールドの三種類の変数がある。
単発の名前はグローバル変数かローカル変数を表す (または関数の仮引数かもしれないが、それはローカル変数の一種である)。
var ::= Name
明示的にローカルと定義されない限り、変数はグローバルとみなされる (2.4.7 を参照)。 ローカル変数は レキシカルスコープ を持ち、 そのスコープ内で定義された関数から自由にアクセスできる (2.6 を参照)。
最初の代入が行われる前の変数の値は nil である。
テーブルをインデックス付けするためには角カッコを使う。
var ::= prefixexp `[´ exp `]´
最初の式 (prefixexp) はテーブル、 二番目の式 (exp) はテーブル内のエントリを指定する値でなければならない。 テーブルのインデックスを指定する式は限定された構文を持つ。 詳細は 2.5 を参照。
構文 var.NAME
は var["NAME"]
の単なるシンタックスシュガーである。
var ::= prefixexp `.´ Name
グローバル変数とテーブルフィールドへアクセスする効果はメタテーブルによって変えられる。
インデックス付き変数 t[i]
へのアクセスは
gettable_event(t,i)
の呼び出しと等価である
(gettable_event
関数の完全な説明は 2.8 を参照。
この関数はLuaで定義したり呼ぶことはできず、単に説明のため用いているだけである)。
すべてのグローバル変数は、環境テーブル または単に 環境 と呼ばれる通常のLuaのテーブル内に、フィールドとして存在している。
Cで書かれLuaへエクスポートされた関数 (Cの関数) はすべて共通の グローバル環境 を共有している。
Luaで書かれた関数 (Luaの関数) はそれぞれ環境への参照を持ち、
その関数内でのすべてのグローバル変数は、その環境テーブルを参照する。
関数が作られたとき、関数は、それが作られた関数から見える環境を受け継ぐ。
Lua関数の環境テーブルを変更したり取得するには、
setfenv
や getfenv
を呼ぶ (5.1 を参照)。
グローバル変数 x
へのアクセスは _env.x
と等価であり、
以下と等価である。
gettable_event(_env, "x")
ただし、_env
は関数が実行されている環境を表す
(変数 _env
はLuaに定義されていない。
これはただ説明のために用いているだけである)。
LuaはPascalやCと同じように一般的な文のセットをサポートしている。 代入、制御構造、関数呼び出し、テーブルコンストラクタや変数の定義などである。
Luaの実行の単位は チャンク と呼ばれる。 チャンクは、単純に、順番に実行される文の連なりである。 それぞれの文末には省略可能なセミコロンを置いても良い。
chunk ::= {stat [`;´]}
Luaはチャンクを無名関数の本体として扱っている (2.5.8 を参照)。 チャンクはそれ自身のローカル変数や戻り値を持つことができる。
チャンクはファイルやホストプログラム内の文字列として格納されているであろう。 チャンクが実行されるとき、まず仮想マシンのオペコードにコンパイルされ、それからコンパイル済みコードが仮想マシンのインタプリタによって実行される。
チャンクはバイナリ形式のコンパイル済みコードであっても良い。
詳細は luac
プログラムを参照。
ソースプログラムとコンパイル済み形式はどちらを用いても良い。
Luaは自動的にファイル形式を検出し、適切に振る舞う。
文の列はブロックである。 構文的には、ブロックはチャンクと等しい。
block ::= chunk
ブロックは明示的に単一の文とすることもある。
stat ::= do block end
明示的なブロックは変数定義スコープをコントロールするのに便利である。 明示的なブロックはまた、 他のブロックの途中に return 文や break 文を入れるために使うこともある。
Luaは多重代入を許している。 だから、代入文では左辺に変数リスト、右辺に式リストを書く。 どちらのリストもそれぞれの要素をカンマで区切る。
stat ::= varlist1 `=´ explist1 varlist1 ::= var {`,´ var} explist1 ::= exp {`,´ exp}
式については 2.5 で議論する。
代入の前に、値リストは変数リストの長さに調節される。 もし必要な数よりも値が多ければ、余分な値は捨てられる。 もし必要な数よりも値が少なければ、必要なだけ nil が追加される。 もし式リストの最後が関数呼び出しなら、調節の前に、その関数のすべての戻り値が値リストに追加される (ただし呼び出しをカッコで囲った場合を除く、2.5 を参照)。
代入文は、まずすべての式を評価し、それから、代入が行われる。 だから、このコード
i = 3 i, a[i] = i+1, 20は、
i
に4が代入される前に a[i]
の i
が (3に) 評価されるため、
a[3]
に20が代入される。
a[4]
は何の影響もない。
同様に、
x, y = y, xは
x
と y
の値を交換する。
グローバル変数とテーブルフィールドへの代入の効果は、メタテーブルによって変えられる。
インデックス付き変数への代入 t[i] = val
は
settable_event(t,i,val)
と等価である
(settable_event
関数の完全な記述は 2.8 を参照。
この関数はLuaで定義したり呼ぶことはできず、
ただ説明のため用いているだけである)。
グローバル変数への代入 x = val
は代入 _env.x = val
と等価であり、
以下と等価である。
settable_event(_env, "x", val)
ただし、_env
は関数が実行されている環境を表す
(変数 _env
はLuaに定義されていない。
これはただ説明のために用いているだけである)。
制御構造 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] end
Luaには for 文もある。 これは2つの種類がある (2.4.5 を参照)。
制御構造の条件式 exp は任意の値をとれる。 false と nil は共に偽である。 nil と false 以外のすべての値は真になる (特に、数値の0や空文字列は真であることに注意)。
return 文は関数やチャンクから値を返すために使う。 関数やチャンクは1個以上の値を返すことができる。 return 文の構文は以下の通り。
stat ::= return [explist1]
break 文は while、repeat、for ループの実行を終了し、 ループの次までスキップする。
stat ::= break
break は最も内側のループを終わらせる。
構文的な理由から、return 文と break 文はブロックの 最後 の文としてのみ書くことが許される。 return や break をブロックの途中で使うことが本当に必要なら、 明示的な内部ブロックを使う次のような慣用句を使えば良い。
do return end do break endこれで return も break も (内部) ブロックの最後の文になる。 実際、これらの慣用句はデバッグ中に使われる。
for 文には、数値用と汎用の2つの形式がある。
数値用 for ループは制御変数が等差数列を辿ってコードブロックを繰り返す。 以下がその構文である。
stat ::= for Name `=´ exp `,´ exp [`,´ exp] do block end
block は name が最初の exp で始まって二番目のexp に達するまで、 三番目の exp ずつ進む間、繰り返される。 より正確には、次のような for 文
for var = 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 block var = var + _step end end
まとめると、
_limit
と _step
は見えない変数である。
この名前は説明のために用いられているだけである。
var
に代入が行われた場合、挙動は 未定義 である。
var
はローカルである。
for 文の外側でその値を使うことはできない。
もしループ変数 var
の値が必要なら、
ループを出る前に別の変数に代入する必要がある。
汎用 for 文は イテレータ と呼ばれる関数を通して働く。 それぞれの繰り返しについて、新しい値を生成するためにイテレータ関数が呼ばれ、nil になったところで止まる。 汎用 for ループは以下の構文である。
stat ::= for Name {`,´ Name} in explist1 do block end
次のような for 文
for var_1, ..., var_n in explist do block endは次のコードと等価である。
do local _f, _s, var_1 = explist local var_2, ... , var_n while true do var_1, ..., var_n = _f(_s, var_1) if var_1 == nil then break end block end end
まとめると、
explist
は一度だけ評価され、
イテレータ 関数、状態、繰り返し変数 の初期値、でなければならない。
_f
と _s
は見えない変数である。
この名前は説明のために用いられているだけである。
var_1
に代入が行われた場合、挙動は 未定義 である。
var
はローカルである。
for 文の外側でその値を使うことはできない。
もしループ変数 var
の値が必要なら、
ループを出る前に別の変数に代入する必要がある。
副作用を許しているため、関数呼び出しは文として実行できる。
stat ::= functioncall
この場合、戻り値はすべて捨てられる。 関数呼び出しは 2.5.7 で説明する。
ローカル変数はブロックの中どこででも定義できる。 定義は初期値の代入を伴う場合がある。
stat ::= local namelist [`=´ explist1] namelist ::= Name {`,´ Name}
もしあれば、多重代入と同じ構文で初期値が代入される (2.4.3 を参照)。 そうでなければ、変数はすべて nil で初期化される。
チャンクもまたブロックであるから (2.4.1 を参照)、 明示的なブロックの外側のチャンクでもローカル変数を定義できる。 そのようなローカル変数はチャンクの終わりで消滅する。
ローカル変数の可視ルールは 2.6 で説明する。
Luaの基本の式を以下に示す。
exp ::= prefixexp exp ::= nil | false | true exp ::= Number exp ::= Literal exp ::= function exp ::= tableconstructor prefixexp ::= var | functioncall | `(´ exp `)´
数値と文字列リテラルは 2.1 で説明した。 変数は 2.3 で説明した。 関数定義は 2.5.8 で説明する。 関数呼び出しは 2.5.7 で説明する。 テーブルコンストラクタは 2.5.6 で説明する。
カッコに囲まれた式は常にただ1つの値を結果とする。
つまり、たとえ f
が複数の値を返しても、(f(x,y,z))
は常に単一の値となる。
(f(x,y,z))
の値は、f
が返す最初の値である。
あるいは f
が何も返さなければ、nil となる。
式は算術演算子、関係演算子、論理演算子からも構成できる。 これらは次で説明する。
Luaは一般的な算術演算子をサポートしている。
+
(加算)、
-
(減算)、*
(乗算)、
/
(除算)、^
(累乗)、
単項の -
(符号反転) など。
もしオペランドが数値、あるいは数値に変換できる文字列 (2.2.1を参照)
なら、累乗以外のすべての演算は通常の意味を持つ。
そうでなければ、適当なメタメソッドが呼ばれる (2.8 を参照)。
累乗はグローバル関数 __pow
を呼ぶ。
標準数学ライブラリは関数 __pow
を定義している (5.5 を参照)。
これは期待される累乗の効果を提供する。
Luaの関係演算子は以下の通りである。
== ~= < > <= >=
これらの演算子は常に false か true いずれかの結果を返す。
等価 (==
) はまずオペランドの型を比較する。
もし型が異なっていたら、結果は false である。
そうでなければ、オペランドの値が比較される。
数値と文字列は一般的な方法で比較する。
オブジェクト (テーブル、ユーザーデータ、スレッド、関数) は 参照 を比較し、
2つのオブジェクトが 同じ オブジェクトである場合だけを等しいとみなす。
新しいオブジェクト (テーブル、ユーザーデータ、関数) を作ったときは常に、
この新しいオブジェクトは、以前に存在していたオブジェクトと異なる。
"eq"メタメソッドを使って、テーブルやユーザーデータをLuaが比較する方法を変えられる (2.8 を参照)。
2.2.1 の変換ルールは等価比較には適用されない。
そのため、"0"==0
は false に評価され、
t[0]
と t["0"]
は異なったテーブルエントリを示す。
演算子 ~=
は正確に等価 (==
) の否定である。
関係演算子は次のように働く。 引数が両方数値ならば、それらは適切に比較される。 もし両方の引数が文字列ならば、現在のロケールに従ってその値が比較される。そうでなければ、Luaは"lt"または"le"メタメソッドを試みる (2.8 を参照)。
Luaの論理演算子は次の通りである。
and or not
制御構造 (2.4.4 を参照) と同じく、 すべての論理演算子は false と nil の両方を偽、それ以外のすべてを真とみなす。
not 演算子は常に false か true を返す。
論理積演算子 and は、最初の引数が false か nil ならその値を返し、そうでなければ二番目の引数を返す。 論理和演算子 or は最初の引数が false か nil 以外ならその値を返し、そうでなければ二番目の引数を返す。 and と or は共にショートカット評価を行う。 つまり、二番目のオペランドは、それが必要なときだけ評価される。 例を挙げると
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
Luaの文字列連結演算子はふたつのドット (`..
´) で表す。
もし両方のオペランドが文字列か数値なら、それらは 2.2.1 で述べたルールに従って文字列に変換される。
そうでなければ、"concat"メタメソッドが呼ばれる (2.8 を参照)。
Luaでの演算子の優先順位を以下の表に示す。 優先順位は低い方から順に
or and < > <= >= ~= == .. + - * / not - (unary) ^
式の優先順位を変えるためにカッコを使うことができる。
連結 (`..
´) と累乗 (`^
´) は右結合である。
他の二項演算子はすべて左結合である。
テーブルコンストラクタはテーブルを作る式である。 コンストラクタが評価されるたびに新しいテーブルが作られる。 空のテーブルを作ることも、いくつかのフィールドに初期値を持ったテーブルを作ることもできる。 コンストラクタの構文は以下の通りである。
tableconstructor ::= `{´ [fieldlist] `}´ fieldlist ::= field {fieldsep field} [fieldsep] field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp fieldsep ::= `,´ | `;´
[exp1] = exp2
形式のフィールドは、
キー exp1
と値 exp2
を持つエントリをテーブルに追加する。
name = exp
形式のフィールドは ["name"] = exp
と等価である。
最後の exp
形式のフィールドは、[i] = exp
と同じである。
ここで i
は1から始まる連続した整数であり、他の形式のフィールドはこのカウンタに影響を与えない。
例えば
a = {[f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45}は以下と等価である。
do local temp = {} temp[f(1)] = g temp[1] = "x" -- 最初のexp temp[2] = "y" -- 2番目のexp temp.x = 1 -- temp["x"] = 1 temp[3] = f(x) -- 3番目のexp temp[30] = 23 temp[4] = 45 -- 4番目のexp a = temp end
もし最後のフィールドが exp
形式で、その式が関数呼び出しであれば、
関数のすべての戻り値がリストに追加される (2.5.7 を参照)。
これを避けるには、関数呼び出しをカッコで囲む (2.5 を参照)。
自動生成コードに便利なように、各フィールドの終わりに省略可能なセミコロンを付けても良い。
Luaの関数呼び出しは以下の構文である。
functioncall ::= prefixexp args
関数呼び出しでは、 まず prefixexp と args が評価される。 もし prefixexp の値が 関数 であれば、与えられた引数でその関数が呼ばれる。 そうでなければ、"call"メタメソッドが呼ばれる。 そのとき prefixexp が最初の引数として渡され、二番目以降に元々の引数が続く (2.8 を参照)。
書式
functioncall ::= prefixexp `:´ Name argsは「メソッド」と呼ばれる。 呼び出し
v:name(...)
は v.name(v, ...)
のシンタックスシュガーであり、
v
の評価がただ一度である点だけが異なる。
引数は以下の構文を持つ。
args ::= `(´ [explist1] `)´ args ::= tableconstructor args ::= Literal
引数のすべての式は呼び出し前に評価される。
f{...}
は f({...})
のシンタックスシュガーであり、新しいテーブルひとつが引数となる。
f'...'
(および f"..."
や f[[...]]
) は
f('...')
のシンタックスシュガーであり、引数は文字列リテラルひとつである。
関数はいくつでも結果を返せる (2.4.4 を参照) ため、戻り値の数は使われる前に調節される。 もし文として関数が呼び出されたら (2.4.6 を参照)、 戻り値リストはゼロ個に調節され、つまりすべての戻り値が捨てられる。 もし他の式の中や式リストの途中で関数が呼び出されたら、 戻り値リストは1個に調節され、最初の1個を除くすべての戻り値は捨てられる。 もし式リストの最後で関数が呼び出されたら、調節は行われない (カッコに囲まれて呼び出された場合を除く)。
いくつか例を挙げる。
f() -- 戻り値が0個に調節される g(f(), x) -- f()の戻り値は1個に調節される g(x, f()) -- xに加えてf()のすべての戻り値をgに渡す a,b,c = f(), x -- f()の戻り値は1個に調節される (そしてcにはnilが入る) a,b,c = x, f() -- f()の戻り値は2個に調節される a,b,c = f() -- f()の戻り値は3個に調節される return f() -- f()の戻り値をすべて返す return x,y,f() -- x、yとf()のすべての戻り値を返す {f()} -- f()のすべての戻り値からなるリストを作る {f(), nil} -- f()の戻り値が1個に調節される
関数呼び出しをカッコで囲めば、その戻り値はちょうどひとつに調節される。
return x,y,(f()) -- x、y、そしてf()の最初の戻り値が返される {(f())} -- ちょうど1個の要素を持つテーブルを作る
Luaのフリーフォーマット構文の例外として、
関数呼び出しの `(
´ の直前で改行することはできない。
この制限によって言語の曖昧さが避けられる。
つまり、この制限がなかった場合、もし次のように書くと
a = f (g).x(a)
Luaは a = f(g).x(a)
と解釈したかもしれない。
この場合、2つの文にしたければ間にセミコロンが必要である。
だか実際には、f
を呼びたければ (g)
の前の改行を取り除かなければならない。
return
functioncall のような呼び出し形式は 終端呼び出し と呼ばれる。
Luaは 終端呼び出し最適化 (または 終端再帰最適化) を実装している。
終端呼び出しでは、呼び出された関数は呼び出し側関数のスタックエントリを再利用する。
その結果、終端呼び出しのネスト数の制限なしに (無限に再帰呼び出しして) プログラムを実行できる。
しかしながら、終端呼び出しは呼び出し側関数に関するデバッグ情報を消してしまう。
終端呼び出しは、単一の関数呼び出しで return するという特別な状況でのみ起こることに注意。
この構文では、呼び出した関数の戻り値がそのまま呼び出し側関数の戻り値になる。
よって、以下の例はすべて、終端呼び出しではない。
return (f(x)) -- 戻り値が1個に調節されている return 2 * f(x) -- 戻り値が加工されている return x, f(x) -- 戻り値が追加されている f(x); return -- 戻り値が捨てられている return x or f(x) -- 戻り値が1個に調節されている
関数定義の構文を以下に示す。
function ::= function funcbody funcbody ::= `(´ [parlist1] `)´ block end
以下のシンタックスシュガーは関数定義を単純化する。
stat ::= function funcname funcbody stat ::= local function Name funcbody funcname ::= Name {`.´ Name} [`:´ Name]
以下の文
function f () ... endは次のように変換される。
f = function () ... end
以下の文
function t.a.b.c.f () ... endは次のように変換される。
t.a.b.c.f = function () ... end
以下の文
local function f () ... endは次のように変換される。
local f; f = function () ... end
関数定義は実行可能な式であり、関数 型の値を持つ。 Luaがチャンクをコンパイルすると、 その中にある関数の本体もコンパイルされる。 そして、Luaが関数定義を実行したとき、 関数は インスタンス化 (または クローズ) される。 この関数インスタンス (または クロージャ) は式の最終的な値である。 同じ関数の異なるインスタンスは異なるローカル変数と異なる環境テーブルを参照する場合がある。
仮引数はローカル変数として振る舞い、渡された実引数の値で初期化される。
parlist1 ::= namelist [`,´ `...´] parlist1 ::= `...´
関数が呼ばれると、実引数リストは仮引数リストの長さに調節される。
ただし、仮引数リストの最後が3つのドット (`...
´) である
可変引数 の場合を除く。
可変引数では実引数が調節されず、代わりに余分の実引数が
arg
という名前の暗黙の仮引数に渡される。
arg
の値はテーブルで、
フィールド n
に余分の実引数の数が格納され、
フィールド 1、2、...n
にその実引数が格納される。
例として、以下の定義を考える。
function f(a, b) end function g(a, b, ...) end function r() return 1,2,3 end
この場合、実引数から仮引数へ以下のようにマッピングされる。
呼び出し 仮引数 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, arg={n=0} g(3, 4) a=3, b=4, arg={n=0} g(3, 4, 5, 8) a=3, b=4, arg={5, 8; n=2} g(5, r()) a=5, b=1, arg={2, 3; n=2}
return 文を使って関数の結果を返す (2.4.4 を参照)。 return 文に出会わずに制御が関数の終わりまで達したら、関数は何も返さない。
コロン 構文を使って メソッド を定義できる。
メソッドとは、暗黙の引数 self
を余分に持つ関数である。
つまり、以下の構文
function t.a.b.c:f (...) ... endは、以下の文のシンタックスシュガーである。
t.a.b.c.f = function (self, ...) ... end
Luaはレキシカルスコープを持つ言語である。 変数のスコープは、それが定義された文の 次 から始まり、 その定義を含む最も内側のブロックのendで終わる。 例を挙げる。
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 (グローバル変数)
local x = x
のような定義に注意。
新しく定義された x
はまだスコープに入っていないので、
右辺の x
は外側の変数を参照する。
レキシカルスコープのルールにより、 ローカル変数はそのスコープの内側に定義された関数から自由にアクセスできる。 例を挙げる。
local counter = 0 function inc (x) counter = counter + x return counter end
内部関数から使われるローカル変数は、 内部関数の中では 上位値 または 外部ローカル変数 と呼ばれる。
local 文を実行するたびに新しいローカル変数が定義されることに注意。 以下の例を考えよ。
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個のインスタンス) を作る。
クロージャはすべて同じ x
を共有するが、
それぞれ異なった y
を持つ。
Luaは拡張言語であるから、 すべてのLuaアクションはホストプログラムのCのコードがLuaライブラリの関数を呼ぶことによってスタートする (3.15 を参照)。 Luaのコンパイル中や実行中でエラーが起きたときは、制御がCに返され、 適切な動作を行うことができる (例えばエラーメッセージを出すとか)。
Luaコードは error
関数を呼ぶことで明示的にエラーを起こすことができる
(5.1 を参照)。
もしLua内でエラーを捕らえる必要があれば、
pcall
関数を使えばよい (5.1 を参照)。
Luaのテーブルとユーザーデータオブジェクトは メタテーブル を持つことができる。
メタテーブル はLuaの通常のテーブルであるが、
テーブルやユーザーデータに対して特殊な演算をしたときの挙動を定義する。
メタテーブルのフィールドを設定することで、オブジェクトの動作をいくつかの面で変えることができる。
例えば、オブジェクトが加算のオペランドになったとき、
Luaはメタテーブルの "__add"
フィールドをチェックする。
もしそれが見つかれば、加算を行うためにその関数が呼ばれる。
メタテーブルのキーを イベント、値を メタメソッド と呼ぶ。
前の例でいうと、"add"
がイベントで、加算を行う関数がメタメソッドである。
オブジェクトのメタテーブルは set/getmetatable
関数を使って変えたり取り出すことができる
(5.1 を参照)。
メタテーブルは、算術演算、関係比較、連結、インデックス付けについて、オブジェクトがどう振る舞うかを制御する。 また、ユーザーオブジェクトに関しては、オブジェクトがガベージコレクトされたときに呼ばれる関数も定義できる。 各演算には イベント と呼ばれる特殊なキーが関連付けられている。 Luaがテーブルやユーザーデータに対してこれらの演算を行うとき、 オブジェクトがメタテーブルを持っていてイベントが設定されているかチェックされる。 キーに割り当てられた値 (メタメソッド) はLuaがその演算をどう行うかをコントロールする。
メタテーブルがコントロールできる演算を以下に示す。
各演算は関連付けられた名前で区別される。
各演算のキーは、その名前の前に2つのアンダースコアが付く文字列である。
例えば、"add"演算のキーは、文字列 "__add"
である。
これらの演算の効果は、いかに演算が実行されるかを記述したLuaの関数で説明する。
ここにLuaのコードを示しているのは、単に説明のためである。
実際はインタプリタにハードコードされており、この擬似コードよりも効率的に動作する。
ここで使われている関数 (rawget
、tonumber
など) は 5.1 に記述されている。
与えられたオブジェクトのメタメソッドを取り出すコードとして、以下の表現を用いているが、
metatable(obj)[event]これは次のように読んでもらいたい。
rawget(metatable(obj) or {}, event)
つまり、メタメソッドへのアクセスで他のメタメソッドを呼び出すことはなく、 オブジェクトがメタメソッドを持っていなくてもエラーを起こすことはない (その場合は単に nil を返す)。
+
演算。
以下の getbinhandler
関数は二項演算でLuaがどのようにハンドラを選ぶかを定義する。
まずLuaは最初のオペランドについて試みる。
もしその型が、その演算についてハンドラを定義していなければ、
二番目のオペランドを試みる。
function getbinhandler (op1, op2, event) return metatable(op1)[event] or metatable(op2)[event] end
この関数を使って op1 + op2
の挙動を示すと、
function add_event (op1, op2) local o1, o2 = tonumber(op1), tonumber(op2) if o1 and o2 then -- 両方のオペランドが数値か? return o1 + o2 -- この `+´ はプリミティブな加算 else -- 少なくとも片方は数値ではない local h = getbinhandler(op1, op2, "__add") if h then -- 両方のオペランドに対してハンドラを呼ぶ return h(op1, op2) else -- ハンドラがない、デフォルトの動作 error("...") end end end
-
演算。
"add"演算と同じように動作する。
*
演算。
"add"演算と同じように動作する。
*
演算。
"add"演算と同じように動作する。
^
(累乗) 演算。
function pow_event (op1, op2) local o1, o2 = tonumber(op1), tonumber(op2) if o1 and o2 then -- 両方のオペランドが数値か? return __pow(o1, o2) -- グローバルの `__pow´ を呼ぶ else -- 少なくとも片方は数値ではない local h = getbinhandler(op1, op2, "__pow") if h then -- 両方のオペランドに対してハンドラを呼ぶ return h(op1, op2) else -- ハンドラがない、デフォルトの動作 error("...") end end end
-
演算。
function unm_event (op) local o = tonumber(op) if o then -- オペランドは数値か? return -o -- この `-´ はプリミティブな符号反転 else -- オペランドは数値でない -- オペランドからハンドラを取り出す local h = metatable(op).__unm if h then -- オペランドと nil でハンドラを呼ぶ return h(op, nil) else -- ハンドラがない、デフォルトの動作 error("...") end end end
..
(連結) 演算。
function 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
==
演算。
関数 getcomphandler
は、比較演算子のメタメソッドをLuaがどのように選ぶかを定義する。
両方のオブジェクトが同じ型で、その演算に対して同じメタメソッドを持つ場合だけ、
メタメソッドが選択される。
function getcomphandler (op1, op2, event) if type(op1) ~= type(op2) then return nil end local mm1 = metatable(op1)[event] local mm2 = metatable(op2)[event] if mm1 == mm2 then return mm1 else return nil end end"eq"イベントは次のように定義される。
function eq_event (op1, op2) if type(op1) ~= type(op2) then -- 型が異なるか? return false -- 異なるオブジェクト end if op1 == op2 then -- プリミティブのイコール return true -- オブジェクトは等しい end -- メタメソッドを試す local h = getcomphandler(op1, op2, "__eq") if h then return h(op1, op2) else return false end end
a ~= b
は not (a == b)
と等価である。
<
演算。
function 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 = getcomphandler(op1, op2, "__lt") if h then return h(op1, op2) else error("..."); end end end
a > b
は b < a
と等価である.
<=
演算。
function 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 = getcomphandler(op1, op2, "__le") if h then return h(op1, op2) else h = getcomphandler(op1, op2, "__lt") if h then return not h(op2, op1) else error("..."); end end end end
a >= b
は b <= a
と等価である。
"le"メタメソッドがなければ、
Luaは a <= b
を not (b < a)
とみなして"lt"を試みることに注意。
table[key]
インデックスアクセス。
function 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
table[key] = value
インデックス代入。
function 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 return h(table, key,value) -- ハンドラを呼ぶか、 else h[key] = value -- 演算を繰り返す。 end
function function_event (func, ...) if type(func) == "function" then return func(unpack(arg)) -- プリミティブの関数呼び出し else local h = metatable(func).__call if h then return h(func, unpack(arg)) else error("...") end end end
Luaは自動的にメモリを管理する。 つまり、新しいオブジェクトのためのメモリ確保や、オブジェクトが要らなくなったときの解放について、悩まなくてよい。 Luaは死んだオブジェクト (もうアクセスできなくなったオブジェクト) を回収する ガベージコレクタ を時々実行することで、自動的にメモリを管理する。 テーブル、ユーザーデータ、関数、スレッド、文字列といったすべてのLuaオブジェクトは自動管理の対象である。
Luaはガベージコレクションの周期を管理する2つの数値を使う。 ひとつはLuaが使用中の動的メモリの量で、もうひとつは閾値である。 使用中のメモリ量が閾値をオーバーしたら、 死んだオブジェクトのメモリを再利用するためにガベージコレクタが動作する。 そして使用中メモリ量のカウンタが更新され、その値の2倍が新たな閾値に設定される。
CのAPIを通してこれらの値を問い合わせたり閾値を変えることができる (3.7 を参照)。
閾値をゼロに設定するとガベージコレクションが直ちに実行され、
大きい値に設定すると、ガベージコレクションが実行されないようになる。
Luaコードでは、gcinfo
関数と collectgarbage
関数を使って、
ガベージコレクションサイクルを多少コントロールできる (5.1 を参照)。
CのAPIを使う場合、ユーザーデータにガベージコレクタメタメソッドを設定できる (2.8を参照)。 このメタメソッドは ファイナライザ と呼ばれることもある。 ファイナライザはLuaのガベージコレクタを外部リソースと共に使えるようにする (ファイルやネットワーク接続、データベース接続などを閉じたり、独自に確保したメモリを解放するとか)。
メタテーブルに __gc
フィールドを持つユーザーオブジェクトが解放されても、ガベージコレクタはそれをすぐには回収しない。
その代わり、Luaはそれをリストに入れる。
他のオブジェクトの回収が終わったあと、Luaはリスト内のユーザーデータに対して以下の関数と同等のことを行う。
function gc_event (udata) local h = metatable(udata).__gc if h then h(udata) end end
各ガベージコレクションサイクルの終わりに、 作られたときと 逆の順番で ユーザーデータのファイナライザが呼ばれる。 つまり、最初に呼ばれるファイナライザは、一番最近に作られたユーザーデータのものである。
弱参照テーブル は 弱参照 な要素を持つテーブルである。 弱参照はガベージコレクタに無視される。 言い換えると、オブジェクトへの参照が弱参照のみであれば、ガベージコレクタはそのオブジェクトを回収してしまう。
弱参照テーブルは、キー、値、あるいはその両方が弱参照である。
弱参照キーを持つテーブルは、キーは回収されるが、その値は回収されない。
弱参照キーと弱参照値の両方を持つテーブルでは、キーも値も回収の対象になる。
キーと値のどちらか一方が回収されると、キーと値のペア全体がテーブルから除去される。
テーブルの弱参照の性質は、メタテーブルの __mode
フィールドで制御できる。
もし __mode
フィールドが文字列で、文字 `k
´ が含まれていたら、テーブルのキーが弱参照となる。
もし __mode
フィールドが文字 `v
´ を含んでいたら、テーブルの値が弱参照となる。
メタテーブルとして使った後に、そのテーブルの __mode
フィールドの値を変更するべきではない。
このメタテーブルで制御されているテーブルの弱参照の挙動が未定義となる。
Luaはコルーチンをサポートしている。 準コルーチン とか 協調的マルチスレッド と呼ばれることもある。 Luaのコルーチンは独立に実行されるスレッドを表現している。 マルチスレッドシステムのスレッドとは違って、 コルーチンはyield関数を呼んで明示的に実行を中断しなければならない。
コルーチンを作るには coroutine.create
を呼ぶ。
関数はひとつだけ引数をとり、それにコルーチンのメイン関数を渡す。
create
関数は新しいコルーチンを作成し、それを操作するためのスレッド型オブジェクトを返す。
コルーチンはすぐには実行されない。
coroutine.create
から返されたスレッドを最初の引数に渡して最初に coroutine.resume
を呼んだとき、
そのメイン関数の最初の行からコルーチンの実行が始まる。
coroutine.resume
に余分の引数を指定すると、それらはコルーチンのメイン関数に渡される。
コルーチンが開始されたら、終わりに達するか yield を呼ぶまで実行される。
コルーチンは2つの方法で実行を終われる。
メイン関数からreturnして (明示的にか、最後の命令が終わって暗黙的にか) 正常終了したときと、
保護されないエラーが起きて異常終了したときである。
最初の場合では、true と、メイン関数からの戻り値を、coroutine.resume
が返す。
エラーの場合は、coroutine.resume
は false とエラーメッセージを返す。
コルーチンは coroutine.yield
を呼ぶことで中断される。
コルーチンが中断されると、対応する coroutine.resume
からすぐに戻る。
コルーチンの中で呼ばれた関数の中で中断されても同様である
(つまり、メイン関数から直接的/間接的に呼ばれた、メイン関数以外の関数の中でも)。
この場合も、coroutine.resume
は true を返す。
coroutine.yield
に引数が渡されていれば、それも返される。
次に同じコルーチンをresumeすると、中断した場所から実行が再開される。
coroutine.resume
に余分な引数を渡すと、coroutine.yield
からそれらが返される。
coroutine.wrap
関数は coroutine.create
と同様にコルーチンを作成するが、
コルーチン自身を返すのではなく、コルーチンをresumeする関数を返す。
その関数に渡された引数はresumeに追加の引数として渡される。
resumeからの戻り値は、最初のひとつ (ブーリアン型のエラーコード) を除いた残りが返される。
coroutine.resume
と違って、
この関数はエラーを捕らえることはなく、内部で起きたエラーは呼び出した側に伝搬する。
例として、次のコードを考える。
function foo1 (a) print("foo", a) return coroutine.yield(2*a) end co = coroutine.create(function (a,b) print("co-body", a, b) local r = foo1(a+1) print("co-body", r) local r, s = coroutine.yield(a+b, a-b) print("co-body", r, s) return b, "end" end) a, b = coroutine.resume(co, 1, 10) print("main", a, b) a, b, c = coroutine.resume(co, "r") print("main", a, b, c) a, b, c = coroutine.resume(co, "x", "y") print("main", a, b, c) a, b = coroutine.resume(co, "x", "y") print("main", a, b)これを実行すると、以下の出力を得る。
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
このセクションではLuaのためのCのAPIを説明する。
これは、ホストプログラムがLuaに働きかけるためのCの関数のセットである。
すべてのAPI関数と、関連する型、定数は、ヘッダーファイル lua.h
で定義されている。
このマニュアルでは「関数」という言葉を使うが、代わりに マクロ として提供されていることもある。 そのようなマクロはすべて、各引数がちょうど一度だけ評価され、隠れた副作用は発生しない (ただし最初の引数を除く。ここには常にLuaステートを渡す)。
Luaライブラリは完全に再入可能である。
グローバル変数はまったく使わない。
Luaインタプリタ全体のステート (グローバル変数やスタックなど) は、
動的に確保される構造体 lua_State
に格納される。
このステートへのポインタは、
無からLuaステートを作成する lua_open
を除いて、
ライブラリのすべての関数で最初の引数として渡さなければならない。
他のAPI関数を呼び出す前に、lua_open
を呼んでステートを作成しなければならない。
lua_State *lua_open (void);
lua_open
で作成したステートを解放するには lua_close
を呼ぶ。
void lua_close (lua_State *L);この関数は、ステート内のすべてのオブジェクトを削除し (もしあればガベージコレクションメタメソッドも呼ぶ)、 ステート内で使われていたすべての動的メモリを解放する。 プラットフォームによっては、ホストプログラムが終了するときにすべてのリソースが自動的に解放されるため、この関数を呼ぶ必要がないかもしれない。 一方、デーモンとかウェブサーバーのような長時間実行するプログラムでは、 消費リソースが増大するのを避けるために、必要なくなったステートはすぐに解放する必要があるだろう。
LuaはCとの間で値を受け渡しするために 仮想スタック を使う。 スタック内の各要素は、Luaの値 (nil、数値、文字列など) を表している。
LuaがCを呼ぶときは、以前のスタックの状態やまだアクティブなCの関数が使っているスタックに影響されないように、新しいスタックを用意する。 このスタックはCの関数に渡された引数が格納されており、 Cの関数から呼び出し側に返す戻り値を格納するためにも使われる (3.16 を参照)。
利便性のため、ほとんどの問い合わせ用API関数は厳密なスタックの規則に従っていない。
代わりに、インデックス を使って、スタック内の任意の要素にアクセスできる。
プラスのインデックスはスタック内の 絶対 位置を表し (1 から始まる)、
マイナスのインデックスはスタックトップからの オフセット を表す。
具体的に言うと、スタックに n 個の要素があるとして、
インデックス1は最初の要素 (つまり、空のスタックに最初に積まれた要素) を表し、
インデックス n は最後の要素を表す。
インデックス-1も最後の要素 (つまりスタックトップにある要素) を表し、
インデックス -n は最初の要素を表す。
有効な インデックスは1からスタックトップの間だけである
(つまり 1 <= abs(index) <= top
)。
lua_gettop
を呼べばいつでもスタックトップのインデックスを得られる。
int lua_gettop (lua_State *L);インデックスは1から始まるので、
lua_gettop
の戻り値はスタック内の要素数に等しい
(0はスタックが空であることを表す)。
LuaのAPIを使うときは、 スタックオーバーフローに気を付けなければならない。 関数
int lua_checkstack (lua_State *L, int extra);はスタックの長さを
top + extra
個の要素が入るように伸ばす。
もしスタックをその長さまで伸ばせなければ、falseを返す。
この関数は、すでにスタックが指定された長さよりも長ければ、
わざわざスタックを縮めたりせず、何も変えないままにおいておく。
LuaがCを呼ぶときは、
最低でも全体で LUA_MINSTACK
個のスタック要素が利用可能である。
LUA_MINSTACK
は lua.h
で20に定義されており、
ループ的にスタックに要素を積んだりしなければ、普通はスタック空間を気にしなくても良い。
多くの問い合わせ関数には、スタック空間内で利用可能な任意のインデックス値を使える。
つまり、lua_checkstack
を使って設定できる最大スタックの長さまでのインデックスである。
このようなインデックスは 受け入れ可能なインデックス と呼ぶ。
もっと正確には、受け入れ可能なインデックス は以下のように定義される。
(index < 0 && abs(index) <= top) || (index > 0 && index <= stackspace)0は決して受け入れ可能なインデックスにならない。
特に明記されていなければ、 どの関数も 疑似インデックス と呼ばれる有効なインデックスを受け付ける。 これはスタック内にないいくつかのLuaの値にCのコードからアクセスするためのものである。 疑似インデックスは、グローバル変数、レジストリ、Cの関数の上位値にアクセスするために使う (3.17 を参照)。
基本的なスタック操作のために以下のAPI関数が提供されている。
void lua_settop (lua_State *L, int index); void lua_pushvalue (lua_State *L, int index); void lua_remove (lua_State *L, int index); void lua_insert (lua_State *L, int index); void lua_replace (lua_State *L, int index);
lua_settop
は受け入れ可能なインデックスおよび0を受け付け、スタックトップをそのインデックスにセットする。
新しいトップが古いトップよりも大きければ、新しい要素は nil で埋められる。
index
が0なら、すべてのスタック要素が消去される。
また、lua.h
で便利なマクロが定義されている。
#define lua_pop(L,n) lua_settop(L, -(n)-1)これはスタックから
n
個の要素を取り除く。
lua_pushvalue
は指定されたインデックスの要素をコピーしてスタックに積む。
lua_remove
は指定された位置の要素を消去し、上の要素をずらして隙間を埋める。
lua_insert
は、指定された位置より上の要素をずらして空きスペースを作り、スタックトップの要素を指定された位置に移動する。
lua_replace
は、どの要素もずらさずに、スタックトップの要素を指定された位置に移す
(要するに指定された位置にあった値は上書きされる)。
これらの関数はすべて、有効なインデックスだけを受け付ける
(lua_remove
や lua_insert
で、スタック位置を表さない疑似インデックスを使ってはならない)。
例として、最初スタックに 10 20 30 40 50*
の値があるとすると
(末尾からトップの順番で、`*
´ がスタックトップを表す)
lua_pushvalue(L, 3) --> 10 20 30 40 50 30* lua_pushvalue(L, -1) --> 10 20 30 40 50 30 30* lua_remove(L, -3) --> 10 20 30 40 30 30* lua_remove(L, 6) --> 10 20 30 40 30* lua_insert(L, 1) --> 30 10 20 30 40* lua_insert(L, -1) --> 30 10 20 30 40* (no effect) lua_replace(L, 2) --> 30 40 20 30* lua_settop(L, -3) --> 30 40* lua_settop(L, 6) --> 30 40 nil nil nil nil*
スタック要素の型をチェックするための以下の関数が利用できる。
int lua_type (lua_State *L, int index); int lua_isnil (lua_State *L, int index); int lua_isboolean (lua_State *L, int index); int lua_isnumber (lua_State *L, int index); int lua_isstring (lua_State *L, int index); int lua_istable (lua_State *L, int index); int lua_isfunction (lua_State *L, int index); int lua_iscfunction (lua_State *L, int index); int lua_isuserdata (lua_State *L, int index); int lua_islightuserdata (lua_State *L, int index);これらの関数はいかなる受け入れ可能なインデックスでも使える。
lua_type
はスタック内の値の型を返し、有効でないインデックス (つまりその位置に要素がない場合) は LUA_TNONE
を返す。
lua_type
が返す値は lua.h
で定義されている以下の定数である。
LUA_TNIL LUA_TNUMBER LUA_TBOOLEAN LUA_TSTRING LUA_TTABLE LUA_TFUNCTION LUA_TUSERDATA LUA_TTHREAD LUA_TLIGHTUSERDATA以下の関数は、これらの定数を文字列に翻訳する。
const char *lua_typename (lua_State *L, int type);
オブジェクトがその型と互換なら lua_is*
関数は1を返し、そうでなければ0を返す。
lua_isboolean
はこのルールの例外であり、ブーリアン型の値だけ1を返す
(つまりこの関数は任意の値がブーリアンと互換であると考えない)。
これらは有効でないインデックスに対しては常に0を返す。
lua_isnumber
は数値か数値的な文字列を受け入れる。
lua_isstring
は文字列と数値を受け入れる (2.2.1 を参照)。
lua_isfunction
はLuaの関数とCの関数を両方受け入れる。
lua_isuserdata
はフルユーザーデータとライトユーザーデータの両方を受け入れる。
Luaの関数とCの関数を区別するには lua_iscfunction
を使う。
ユーザーデータがフルかライトを区別するには lua_islightuserdata
を使う。
数値と数値的な文字列を区別するには lua_type
を使う。
また、スタック内の2つの値を比較するAPI関数もある。
int lua_equal (lua_State *L, int index1, int index2); int lua_rawequal (lua_State *L, int index1, int index2); int lua_lessthan (lua_State *L, int index1, int index2);
lua_equal
と lua_lessthan
は、Luaのと同じである (2.5.2 を参照)。
lua_rawequal
はメタメソッドを呼ばずに、プリミティブの等価比較を行う。
これらの関数は、インデックスが有効でないときは0(false)を返す。
スタック内の値を特定のCの型に変換するために、以下の変換関数がある。
int lua_toboolean (lua_State *L, int index); lua_Number lua_tonumber (lua_State *L, int index); const char *lua_tostring (lua_State *L, int index); size_t lua_strlen (lua_State *L, int index); lua_CFunction lua_tocfunction (lua_State *L, int index); void *lua_touserdata (lua_State *L, int index); lua_State *lua_tothread (lua_State *L, int index); void *lua_topointer (lua_State *L, int index);これらの関数には、任意の受け入れ可能なインデックスを使える。 有効でないインデックスで呼び出すと、間違った型の値を持っているときのように振る舞う。
lua_toboolean
は、指定されたインデックスのLuaの値をCの"boolean"値(0か1)に変換する。
Luaでの条件判断のように、lua_toboolean
は false と nil 以外のすべての値に対して1を返し、そうでなければ0を返す。
有効でないインデックスで呼ばれたときは0を返す。
もし本当のブーリアン値だけを調べたい場合は、lua_isboolean
で値の型を判定すること。
lua_tonumber
は指定されたインデックスのLuaの値を数値に変換する
(デフォルトでは lua_Number
は double
である)。
そのLuaの値は、数値か、数値に変換できる文字列でなければならない (2.2.1 を参照)。
それ以外の場合、lua_tonumber
は0を返す。
lua_tostring
は指定されたインデックスのLuaの値を文字列 (const char*
) に変換する.
Luaの値は文字列か数値でなければならず、それ以外では NULL
を返す。
もしその値が数値であれば、lua_tostring
はスタック内の値を本当に文字列に変えてしまう
(この変換はキーに対して lua_tostring
を使ったときに lua_next
を混乱させる)。
lua_tostring
は、Luaステート内の文字列を指す、完全に配置されたポインタを返す。
この文字列は、その最後に必ずゼロ ('\0'
) を持つ (Cでよくやるように) が、
その途中にもゼロを含むことがある。
文字列中にゼロが含まれるかもしれないのであれば、
実際の長さを調べるために lua_strlen
を使う。
Luaはガベージコレクションを持っているため、
lua_tostring
から返されたポインタが、
その値がスタックから取り除かれた後も未だ有効であるとは保証できない。
もし今関数から返された文字列が、もっと後でも必要になるなら、
それをコピーしておくか、レジストリに置いておく必要がある (3.18 を参照)。
lua_tocfunction
はスタック内の値をCの関数に変換する。
この値はCの関数でなければならず、それ以外ではNULL
を返す。
lua_CFunction
型は 3.16 で説明する。
lua_tothread
はスタック内の値をLuaのスレッド (lua_State*
で表される) に変換する。
この値はスレッドでなければならず、それ以外では NULL
を返す。
lua_topointer
はスタック内の値をCの汎用ポインタ (void *
) に変換する。
この値は、ユーザーデータ、テーブル、スレッド、関数のいずれかである。
それ以外なら lua_topointer
は NULL
を返す。
Luaは同じ型の異なるオブジェクトに対しては異なるポインタを返すことを保証する。
ポインタからその元の値に変換する直接的な方法は無い。
典型的には、この関数はデバッグ情報に使われる。
lua_touserdata
は 3.8 で説明する。
スタックに値を積む以下のAPI関数が提供されている。
void lua_pushboolean (lua_State *L, int b); void lua_pushnumber (lua_State *L, lua_Number n); void lua_pushlstring (lua_State *L, const char *s, size_t len); void lua_pushstring (lua_State *L, const char *s); void lua_pushnil (lua_State *L); void lua_pushcfunction (lua_State *L, lua_CFunction f); void lua_pushlightuserdata (lua_State *L, void *p);
これらの関数はCの値を受け取り、それを対応するLuaの値に変換し、スタックに積む。
特に、lua_pushlstring
と lua_pushstring
は与えられた文字列を内部的にコピーする。
lua_pushstring
は正しいCの文字列 (ゼロで終わる、途中にゼロを含まない文字列) を積むためだけに使える。
それ以外には、明示的に長さを指定できる、より汎用的な lua_pushlstring
を使うべきである。
また、書式化文字列を積むこともできる。
const char *lua_pushfstring (lua_State *L, const char *fmt, ...); const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp);これらの関数は書式化文字列をスタックに積み、その文字列を指すポインタを返す。 これらは
sprintf
や vsprintf
に似ているが、いくつかの重要な違いがある。
`%%´ (文字 `%´) `%s´ (長さ指定のないゼロ終端文字列) `%f´ (lua_Number) `%d´ (int) `%c´ (文字としての int)だけが使える。
関数
void lua_concat (lua_State *L, int n);はスタックトップから
n
個の値を連結し、それらを取り除き、
結果をスタックトップに載せる。
もし n
が1ならば、結果はその1つの文字列である (要するに何もしない)。
もし n
が0ならば、結果は空文字列である。
連結は通常のLuaの意味論に従って行われる (2.5.4 を参照)。
Luaはガベージコレクションを制御するために2つの値、カウンタ と 閾値 を使う (2.9 を参照)。 最初の値はLuaで使われているメモリ量を表し、それが閾値まで達するとガベージコレクタを走らせる。 コレクションが終わった後、使用メモリ量は更新され、閾値はその2倍に設定される。
以下の関数を使って、これら2つの現在値を調べられる。
int lua_getgccount (lua_State *L); int lua_getgcthreshold (lua_State *L);返される値は共にキロバイトである。 以下の関数で閾値を変える。
void lua_setgcthreshold (lua_State *L, int newthreshold);もう一度言うが、
newthreshold
の値はキロバイトである。
この関数が呼ばれたとき、Luaは新しい閾値をセットして、カウンタと比べる。
もし新しい閾値がカウンタよりも小さければ、すぐにガベージコレクタを動かす。
特に、lua_setgcthreshold(L,0)
は強制的にガベージコレクションを行う。
コレクションの後、前述のルールに従って新しい閾値が設定される。
ユーザーデータはLua内でCの値を表現する。 Luaは2種類の異なるユーザーデータ、フルユーザーデータ と ライトユーザーデータ をサポートしている。
フルユーザーデータはメモリブロックを表す。 それは (テーブルと同じように) オブジェクトである。 作成する必要があり、独自のメタテーブルを持つことができ、回収されるのを検出できる。 フルユーザーデータは (rawequal の下では) それ自身と比較したときだけ等しい。
ライトユーザーデータはポインタを表す。 それは (数値と同じように) 値である。 作成はせず、メタテーブルも持たず、(作成されないので) 回収もされない。 ライトユーザーデータは、同じCのアドレスを持つ「どの」ライトユーザーデータとも等しい。
Luaのコードでは、あるユーザーデータがフルかライトかを区別する方法はなく、どちらも userdata
型である。
Cのコードでは、lua_type
はフルユーザーデータに対しては LUA_TUSERDATA
を返し、ライトユーザーデータには LUA_TLIGHTUSERDATA
を返す。
新しいフルユーザーデータを作成するには以下の関数を使う。
void *lua_newuserdata (lua_State *L, size_t size);この関数は指定されたサイズの新しいメモリブロックを確保し、 そのブロックアドレスを持つ新しいユーザーデータをスタックに積み、アドレスを返す。
ライトユーザーデータをスタックに積むには
lua_pushlightuserdata
を使う (3.6 を参照)。
lua_touserdata
はユーザーデータの値を取り出す (3.5 を参照)。
フルユーザーデータの場合はブロックのアドレスを返し、
ライトユーザーデータの場合はそのポインタを返し、
ユーザーデータでなければ、NULL
を返す。
Luaがフルユーザーデータを回収するときは、
もしあれば、ユーザーデータの gc
メタメソッドを呼び、
その後ユーザーデータに関連するメモリを解放する。
オブジェクトのメタテーブルを操作するには以下の関数を使う。
int lua_getmetatable (lua_State *L, int index); int lua_setmetatable (lua_State *L, int index);
lua_getmetatable
は、指定されたオブジェクトのメタテーブルをスタックに積む。
もしインデックスが有効でないか、オブジェクトがメタテーブルを持っていなければ、
lua_getmetatable
はゼロを返し、スタックには何も積まない。
lua_setmetatable
はスタックトップからテーブルを取り出し、
指定されたオブジェクトのための新しいメタテーブルとしてセットする。
もしそのオブジェクトにメタテーブルをセットできなければ
(つまり、そのオブジェクトがユーザーデータでもテーブルでもなければ)、
lua_setmetatable
は0を返すが、テーブルはスタックから取り出される。
lua_load
を使ってLuaチャンクをロードできる。
typedef const char * (*lua_Chunkreader) (lua_State *L, void *data, size_t *size); int lua_load (lua_State *L, lua_Chunkreader reader, void *data, const char *chunkname);
lua_load
の戻り値は以下の通りである。
LUA_ERRSYNTAX
---
コンパイル中に構文エラーが発生
LUA_ERRMEM
---
メモリ割り当てエラー
lua_load
はコンパイルされたチャンクをスタックトップにLua関数として積む。
そうでなければ、エラーメッセージが積まれる。
lua_load
はチャンクがテキストかバイナリか自動的に判定し、適切にそれをロードする (luac
プログラムを参照)。
lua_load
はチャンクを読み込むために、ユーザー提供の リーダー (reader) 関数を使う。
チャンクの新たなピースが必要になるたびに、data
引数を付けて lua_load
がリーダーを呼ぶ。
リーダーはチャンクの新しいピースを埋めたメモリブロックを指すポインタを返し、その長さを size
にセットしなければならない。
チャンクの最後に達したことを伝えるには NULL
を返す。
リーダー関数は1以上の任意の長さのピースを返すことができる。
現在の実装では、リーダー関数はいかなるLua関数も呼ぶことができない。
安全のため、Luaステートには常に NULL
が渡される。
chunkname はエラーメッセージとデバッグ情報に使われる (4 を参照)。
lua_load
の使い方のサンプルや、
ファイルや文字列からチャンクを読み込む出来合いの関数が、
補助ライブラリ (lauxlib.c
) にある。
テーブルを作るには以下の関数を呼ぶ。
void lua_newtable (lua_State *L);この関数は、新しい空のテーブルを作り、スタックに積む。
スタック中にあるテーブルから値を読むには以下の関数を呼ぶ。
void lua_gettable (lua_State *L, int index);
index
はテーブルの位置を指す。
lua_gettable
はスタックトップからキーを取り出し、テーブルのそのキーの内容をスタックに返す。
テーブルはスタックに残ったままになる。
Luaでは、この関数は"index"イベントのメタメソッドを起動する場合がある (2.8 を参照)。
メタメソッドを呼ばずにテーブルから本当の値を得るには raw バージョンを使う。
void lua_rawget (lua_State *L, int index);
スタック中にあるテーブルに値を格納するには、 キーと値をスタックに積んて以下の関数を呼ぶ。
void lua_settable (lua_State *L, int index);
index
はテーブルの位置を指す。
lua_settable
はスタックからキーと値の両方を取り除く。
テーブルはスタックに残ったままになる。
Luaでは、この操作は"settable"や"newindex"イベントのメタメソッドを起動する場合がある。
メタメソッドを呼ばずにテーブルに本当に値を格納するには raw バージョンを使う。
void lua_rawset (lua_State *L, int index);
テーブルを巡回するには以下の関数を使う。
int lua_next (lua_State *L, int index);
index
は巡回したいテーブルを指す。
この関数はスタックからキーを取り出し、テーブル内のキー・値のペア (与えられたキーの「次」のペア) を積む。
これ以上要素がなければ、lua_next
は0を返す (何も積まない)。
巡回の最初には nil キーを使う。
典型的な巡回は次のようになる。
/* テーブルはスタックの `t´ の位置にあるとする */ lua_pushnil(L); /* first key */ while (lua_next(L, t) != 0) { /* `キー´ は -2、`値´ は -1 の位置に */ printf("%s - %s\n", lua_typename(L, lua_type(L, -2)), lua_typename(L, lua_type(L, -1))); lua_pop(L, 1); /* `値´を除去、`キー´ は次の繰り返しのために残す */ }
テーブルを巡回する間、キーが本物の文字列であるかどうか判らないなら、キーに対して直接 lua_tostring
を呼んではならない。
lua_tostring
は、そのインデックスにある値を 変える ため、lua_next
を混乱させることを覚えておくように。
すべてのグローバル変数は、環境と呼ばれる通常のLuaテーブルに格納されている。
初期値の環境はグローバル環境と呼ばれる。
このテーブルはいつでも疑似インデックス LUA_GLOBALSINDEX
でアクセスできる。
グローバル変数の値を変更するには、環境テーブルに対して通常のテーブル操作を使う。 例えば、グローバル変数の値を取り出すには以下のようにする。
lua_pushstring(L, varname); lua_gettable(L, LUA_GLOBALSINDEX);
Luaスレッドのグローバル環境を変えるために lua_replace
を使うことができる。
以下の関数はLua関数の環境を調べたり変更したりする。
void lua_getfenv (lua_State *L, int index); int lua_setfenv (lua_State *L, int index);
lua_getfenv
はスタック内のインデックス index
が指す関数の環境テーブルをスタックトップに積む。
もし関数がC関数なら、lua_getfenv
はグローバル環境を積む。
lua_setfenv
はスタックからテーブルを取り出し、
インデックス index
が指す関数の新しい環境テーブルにセットする。
index
がLua関数でなければ、lua_setfenv
は0を返す。
3.13 - 配列としてテーブルを使う
配列としてテーブルを使う、すなわち数値だけをインデックスとしてテーブルを使う場合、以下の関数が便利である。
void lua_rawgeti (lua_State *L, int index, int n); void lua_rawseti (lua_State *L, int index, int n);
lua_rawgeti
はスタック位置 index
が指すテーブルの n 番目の要素の値をスタックに積む。
lua_rawseti
はスタック位置 index
が指すテーブルの n 番目の要素に、スタックトップの値を格納し、
スタックからその値を取り除く。
Luaで定義された関数も、Luaに登録されたCの関数も、ホストプログラムから呼び出すことができる。 これは以下のような手順で行う。 まず、呼びたい関数をスタックに積む。 次に、その関数に渡す引数を 順番通りに 積む。 つまり、最初の引数を最初に積む。 最後に、以下の関数を呼ぶ。
void lua_call (lua_State *L, int nargs, int nresults);
nargs
はスタックに積んた引数の数である。
すべての引数と呼びたい関数の値は、スタックから取り除かれ、関数の戻り値が積まれる。
戻り値の数は nresults
に調節される。
nresults
に LUA_MULTRET
を指定した場合は調節されない。
この場合、関数から返されるすべての値が積まれる。
Luaは戻り値をスタック空間に合うようにする。
関数の戻り値は、スタックに順番通りに積まれる
(最初の戻り値は最初に積まれ、スタックトップには最後の値が来る)。
以下の例は、このLuaコードと同じことをホストプログラムでするにはどうすれば良いかを示す。
a = f("how", t.x, 14)Cでは次のようになる。
lua_pushstring(L, "t"); lua_gettable(L, LUA_GLOBALSINDEX); /* グローバルな `t´ (後で使う) */ lua_pushstring(L, "a"); /* 変数名 */ lua_pushstring(L, "f"); /* 関数名 */ lua_gettable(L, LUA_GLOBALSINDEX); /* 呼びたい関数 */ lua_pushstring(L, "how"); /* 最初の引数 */ lua_pushstring(L, "x"); /* 文字列"x"を積む */ lua_gettable(L, -5); /* t.x (2番目の引数) を積む */ lua_pushnumber(L, 14); /* 3番目の引数を積む */ lua_call(L, 3, 1); /* 3個の引数を渡して関数を呼び、1個の戻り値を受け取る */ lua_settable(L, LUA_GLOBALSINDEX); /* グローバル変数`a´をセット */ lua_pop(L, 1); /* `t´をスタックから取り除く */上記のコードは「整合が取れている」ことに注目。 最終的にスタックは元の状態に戻っている。 これは良いプログラミング作法と考えられる。
(この例はLuaのAPIで直接提供される関数のみを使ってすべての詳細を示したものである。 通常プログラマはLuaへの高水準なアクセスを提供するいくつかのマクロや補助ライブラリを定義して使う。 例えば標準ライブラリのソースコードを見よ。)
lua_call
で関数を呼び出すと、その中で起こったエラーは上方へ (longjmp
を使って) 伝搬される。
エラーを処理する必要があれば、lua_pcall
を使うべきである。
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
nargs
と nresults
は lua_call
と同じである。
もしエラーがなければ、lua_pcall
は lua_call
とまったく同じように動作する。
しかし、何かエラーが起きた場合は、lua_pcall
はそれを捕らえて、1つの値 (エラーメッセージ) をスタックに積んでエラーコードを返す。
lua_call
同様、lua_pcall
は常に関数とその引数をスタックから取り除く。
もし errfunc
が0であれば、返されたエラーメッセージは元のエラーメッセージである。
そうでなければ、errfunc
は エラーハンドラ関数
のスタックインデックスを指定する
(現在の実装では、疑似インデックスは指定できない)。
実行時エラーが起きると、エラーメッセージを引数としてこの関数が呼ばれ、
その戻り値が lua_pcall
から返されるエラーメッセージとなる。
典型的には、エラーハンドラ関数は、エラーメッセージにスタックトレースのようなデバッグ情報を付け加えるのに使う。
そのテの情報は、lua_pcall
から戻った後にはもうスタックから除去されているため、集めることができない。
lua_pcall
は成功時は0を返し、エラーの場合は以下のエラーコードのいずれかを返す (lua.h
で定義されている)。
LUA_ERRRUN
--- 実行時エラー。
LUA_ERRMEM
--- メモリ確保エラー。このようなエラーでは、Luaはエラーハンドラ関数を呼ばない。
LUA_ERRERR
--- エラーハンドラ関数内のエラー。
LuaはCで書かれた関数で拡張できる。
これらの関数は lua_CFunction
型でなければならない。
これは次のように定義されている。
typedef int (*lua_CFunction) (lua_State *L);Cの関数はLuaステートを受け取り、Luaに返す戻り値の数を返す。
適切にLuaとやりとりするために、Cの関数は、パラメータや戻り値の受け渡し方法を定義する以下の手順に従わなければならない。 Cの関数はLuaからの引数をスタックから受け取る。 引数は順番通りに置かれている (最初の引数が最初に積まれている)。 つまり関数の開始時点では、 最初の引数 (もしあれば) はインデックスが1である。 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, "関数`average´の引数が正しくない"); lua_error(L); } sum += lua_tonumber(L, i); } lua_pushnumber(L, sum/n); /* 最初の戻り値 */ lua_pushnumber(L, sum); /* 二番目の戻り値 */ return 2; /* 戻り値の数 */ }
Cの関数をLuaに登録するための以下のような便利なマクロがある。
#define lua_register(L,n,f) \ (lua_pushstring(L, n), \ lua_pushcfunction(L, f), \ lua_settable(L, LUA_GLOBALSINDEX)) /* lua_State *L; */ /* const char *n; */ /* lua_CFunction f; */Lua内での関数名と関数へのポインタを渡す。 これを使って、上記のCの関数
foo
を average
としてLuaに登録するには、次のようにする。
lua_register(L, "average", foo);
Cの関数作ったら、いくつかの値を関連付けてCのクロージャを作ることができる。 これらの値は関数が呼ばれたときにいつでもアクセスできる。 Cの関数に値を関連付けるには、まずその値をスタックに積み (複数の値がある場合は最初の値を最初に積む)、 Cの関数をスタックに積むために
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);を呼ぶ。
n
はいくつの値をこの関数に関連付けるかを指定する
(lua_pushcclosure
はこれらの値をスタックから取り出す)。
実をいえば、lua_pushcfunction
は n
を0として lua_pushcclosure
を呼び出すマクロである。
さて、Cの関数が呼ばれると、特別な疑似インデックスにこれらの値が配置される。
これらの疑似インデックスはマクロ lua_upvalueindex
で生成される。
関数に関連付けられた最初の値は lua_upvalueindex(1)
の位置にあり、残りも同様である。
現在の関数の上位値の数よりも大きい n で
lua_upvalueindex(n)
を呼び出しても、
受け入れ可能な (ただし有効でない) インデックスが生成される。
Cの関数とクロージャのサンプルは、公式Luaディストリビューションの標準ライブラリ (src/lib/*.c
) を参照せよ。
Luaはレジストリを提供している。
これは定義済みのテーブルで、好きなLuaの値を格納するためにCのコードから使うことができる。
特に、Cの関数のスコープを超えてLuaの値を保持したいときに有用である。
このテーブルは疑似インデックス LUA_REGISTRYINDEX
でいつでもアクセスできる。
すべてのCのライブラリがデータを保持するためにこのテーブルを使うので、
他のライブラリと衝突しないキーを選ぶ必要がある。
典型的には、ライブラリ名を含む文字列とか、自分のコードで使っているCオブジェクトのアドレスを持つライトユーザーデータを、キーとして使うと良い。
レジストリ内の整数キーは、補助ライブラリで実装されているリファレンスメカニズムで使われており、それゆえ他の目的に使うべきでない。
内部的に、Luaはエラー処理のためにCの longjmp
の機能を使う。
Luaがエラーに直面すると (メモリ不足とか、型エラーとか、構文エラーなど)、
エラーを 発生 させ、つまるところロングジャンプが行われる。
保護された環境 は復帰点をセットするために setjmp
を使い、
エラーは最も最近作られたアクティブ復帰点にジャンプすることになる。
保護された環境の外でエラーが起きると、Luaは パニック関数 を呼び、exit(EXIT_FAILURE)
する。
パニック関数は以下の関数で設定できる。
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);パニック関数では、呼び出し元に戻ることによってアプリケーションが終了するのを避けられる (例えばロングジャンプを実行して)。 しかしいずれにしろ、関連するLuaステートは正常な状態ではなく、closeすることが唯一の安全な操作である。
APIのほとんどの関数はエラー、例えばメモリ確保エラーなどを起こす可能性がある。
以下の関数は保護モード (つまり、実行するために保護された環境を作る) で実行するため、決してエラーを起こさない。
lua_open
, lua_close
, lua_load
, lua_pcall
.
与えられたCの関数を保護モードで実行する、さらにもうひとつの関数がある。
int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
lua_cpcall
は func
を保護モードで呼ぶ。
func
はスタックに1個の引数、ud
を持つライトユーザーデータが載った状態で開始する。
エラーが起こった場合、lua_cpcall
は
lua_pcall
と同じエラーコードを返し、エラーオブジェクトをスタックに置く (3.15 を参照)。
そうでなければ0を返し、スタックは何も変えない。
func
から返される値はすべて捨てられる。
以下の関数を呼ぶと、CのコードからLuaのエラーを発生させることが出来る。
void lua_error (lua_State *L);呼ぶ前に、エラーメッセージ (実際にはどんな型の値でも良い) をスタックトップに置かなければならない。 この関数はロングジャンプを行うので、決して戻ってこない。
Luaはマルチスレッド実行を部分的にサポートする。 もしマルチスレッドをサポートするCのライブラリを持っているのなら、 Luaでその機能を実装するために、それと協調させることができる。 また、Luaはスレッド上で動く独自のコルーチンシステムも実装している。 Luaで新しいスレッドを作るには以下の関数を使う。
lua_State *lua_newthread (lua_State *L);この関数はスタックにスレッドを積み、この新しいスレッドを表す
lua_State
へのポインタを返す。
この関数から返される新しいステートは、すべてのグローバルなオブジェクト (テーブルのような) を元のステートと共有するが、
ランタイムスタックは独立している。
各スレッドは独立したグローバル環境テーブルを持っている。 スレッドを作ったときは、このテーブルは元のステートのものと同じであるが、それぞれ独立に変更できる。
スレッドを閉じたり削除する明示的な関数はない。 他のLuaオブジェクト同様、スレッドはガベージコレクションの対象である。
コルーチンとしてスレッドを操作するための以下の関数が提供される。
int lua_resume (lua_State *L, int narg); int lua_yield (lua_State *L, int nresults);コルーチンを開始するために、まず新しいスレッドを作り、本体となる関数と追加の引数をスタックに積まなければならない。 それから、
narg
に引数の数を渡して lua_resume
を呼ぶ。
コルーチンが中断されたり実行終了したら、呼び出しから戻る。
戻ってきたとき、スタックには lua_yield
に渡された値か、本体の関数から返された戻り値だけが積まれている。
コルーチンの実行中にエラーが起きなければ lua_resume
は0を返す。
エラーが起きたらエラーコードを返し (3.15 を参照)、
スタックにはエラーメッセージが積まれる。
コルーチンを再開するには、yield
から返す値だけをスタックに入れて lua_resume
を呼ぶ。
lua_yield
は以下のようにCの関数のreturn式でだけ呼ぶことができる。
return lua_yield (L, nresults);Cの関数がこの方法で
lua_yield
を呼ぶとコルーチンの実行は中断され、
このコルーチンを開始した lua_resume
の呼び出しから戻る。
引数 nresults
は lua_resume
から返したいスタック上の値の数である。
2つのスレッド間で値を交換するには、lua_xmove
を使う。
void lua_xmove (lua_State *from, lua_State *to, int n);これは
from
のスタックから n
個の値を取り出し、それらを to
のスタックに積む。
Luaはビルトインデバッグ機能を持たない。 代わりに、そのための関数と フック による特殊なインタフェイスを提供している。 このインタフェイスで、デバッガ、プロファイラ、その他のツールのように、インタプリタの「内部情報」を必要とする様々な種類のものを作れるようになっている。
インタプリタ実行時スタックに関する情報を得る主な関数は
int lua_getstack (lua_State *L, int level, lua_Debug *ar);この関数は
lua_Debug
構造体の一部を、
指定されたレベルで実行している関数の アクティベーションレコード で埋める。
レベル0は現在走っている関数で、
レベル n+1 はレベル n の呼び出し元である。
エラーがなければ lua_getstack
は1を返す。
スタックの深さよりも大きいレベルが指定された場合は0を返す。
構造体 lua_Debug
はアクティブな関数に関する色々な情報を格納するのに使う。
typedef struct lua_Debug { int event; const char *name; /* (n) */ const char *namewhat; /* (n) `global', `local', `field', `method' */ const char *what; /* (S) `Lua' 関数, `C' 関数, Lua `main' */ const char *source; /* (S) */ int currentline; /* (l) */ int nups; /* (u) 上位値の数 */ int linedefined; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* 内部用メンバ */ ... } lua_Debug;
lua_getstack
は後で使うために、この構造体の内部用メンバだけを埋める。
lua_Debug
の他のフィールドを役に立つ情報で埋めるには、以下の関数を呼ぶ。
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);エラー (例えば
what
に不正な値を指定したとか) がなければ0を返す。
文字列 what
の各文字は、構造体 ar
のどのフィールドを埋めるかを選択する。
これは上記の lua_Debug
の定義でカッコ内に書かれた文字で指示する。
`S
´ はフィールド source
、linedefined
、what
を埋め、
`l
´ はフィールド currentline
を埋め、以下同様。
さらに、`f
´ は指定されたレベルで走っている関数をスタックに積む。
アクティブでない (スタック中にない) 関数の情報を得るには、
それをスタックに積んで what
を文字 `>
´ で始まる文字列にする。
例えば f
が定義された行番号を知りたい場合は、次のように書く。
lua_Debug ar; lua_pushstring(L, "f"); lua_gettable(L, LUA_GLOBALSINDEX); /* グローバルの `f' */ lua_getinfo(L, ">S", &ar); printf("%d\n", ar.linedefined);
lua_Debug
のフィールドは以下の意味を持つ。
source
関数が文字列内で定義されていれば source
はその文字列である。
関数がファイル内で定義されていれば source
は `@
´ の後にファイル名が続く。
short_src
エラーメッセージに使う、「可読」バージョンの source
。
linedefined
関数定義の開始位置の行番号。
what
Luaの関数なら "Lua"
、
Cの関数なら "C"
、
チャンクのメインパートであれば "main"
、
この関数が終端呼び出しされていたら "tail"
。
最後のケースでは、Luaはこの関数について他に何も情報を持っていない。
currentline
現在実行中の行番号。
この情報が利用可能でなければ currentline
は-1に設定される。
name
その関数に対する適当な名前。
Luaの関数はファーストクラスであるため、固定の名前は持っていない。
複数のグローバル変数に格納される関数もあれば、テーブルフィールドにのみ格納されるものもある。
lua_getinfo
関数は、その関数がどのように呼ばれたか、グローバル変数の値になっているかをチェックして、良さそうな名前を探す。
名前が見つからなければ、name
は NULL
に設定される。
namewhat
name
フィールドを説明する。
namewhat
は、どのように関数が呼ばれたかによって、以下のいずれかになる。
"global"
, "local"
, "method"
,
"field"
, ""
(空文字列。他に適当なものがなければこれを使う)。
nups
関数の上位値の数。
ローカル変数と上位値の操作について、デバッグインタフェイスではインデックスを使う。 最初の仮引数またはローカル変数はインデックス1で、以下同様に最後の可視ローカル変数まで続く。 上位値は関数全体を通してアクティブであるが、特定の順序はない。
以下の関数を使って、指定されたアクティベーションレコードのローカル変数を操作できる。
const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n); const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);引数
ar
には、
事前に lua_getstack
を呼んで埋めるか、
フック (4.3 を参照) に渡された引数を使うかして、
有効なアクティベーションレコードを与えなければならない。
lua_getlocal
はインデックス n
のローカル変数を取得し、その値をスタックに積み、その名前を返す。
lua_setlocal
はスタックトップの値をその変数に格納し、その名前を返す。
どちらの関数も、インデックスが可視ローカル変数の数より大きい場合は NULL
を返す。
以下の関数を使って関数の上位値 (ローカル変数と違って、関数がアクティブでなくなったときもアクセス可能な上位値) を操作できる。
const char *lua_getupvalue (lua_State *L, int funcindex, int n); const char *lua_setupvalue (lua_State *L, int funcindex, int n);これらの関数は共にLuaの関数でもCの関数でも働く (Luaの関数の上位値は、関数が使っている外部ローカル変数で、クロージャに取り込まれたもの)。
funcindex
はスタック内の関数を指す。
lua_getpuvalue
はインデックス n
の上位値を取得し、その値をスタックに積み、その名前を返す。
lua_setupvalue
はスタックトップの値をその上位値に格納し、その名前を返す。
どちらの関数も、インデックスが上位値の数より大きい場合は NULL
を返す。
Cの関数では、どの上位値も名前は ""
である。
例として、以下の関数は指定されたスタックレベルの関数が持っているすべてのローカル変数と上位値の名前一覧を出す。
int listvars (lua_State *L, int level) { lua_Debug ar; int i; const char *name; if (lua_getstack(L, level, &ar) == 0) return 0; /* 失敗、スタック内に指定されたレベルがない */ i = 1; while ((name = lua_getlocal(L, &ar, i++)) != NULL) { printf("local %d %s\n", i-1, name); lua_pop(L, 1); /* ローカル変数を取り除く */ } lua_getinfo(L, "f", &ar); /* 関数を問い合わせ */ i = 1; while ((name = lua_getpuvalue(L, -1, i++)) != NULL) { printf("upvalue %d %s\n", i-1, name); lua_pop(L, 1); /* 上位値を取り除く */ } return 1; }
Luaはフックのメカニズムを提供している。 フックはプログラム実行中に呼ばれるユーザー定義のCの関数である。 フックは以下の4つのイベントで呼ばれる。
call イベント ... Luaが関数を呼ぶとき。 return イベント ... Luaが関数から戻るとき。 line イベント ... Luaが新しい行のコードの実行を開始するとき。 count イベント ... "count" 命令が実行されるたびに。
フックは以下のように定義される lua_Hook
型である。
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);このフックを以下の関数で設定できる。
int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
func
はフックである。
mask
はどのイベントでフックが呼ばれるかを定数
LUA_MASKCALL
、
LUA_MASKRET
、
LUA_MASKLINE
、
LUA_MASKCOUNT
の論理和で指定する。
count
はmaskが LUA_MASKCOUNT
を含むときだけ意味を持つ。
それぞれにイベントについて以下の状況でフックが呼ばれる。
count
命令を実行した直後に呼ばれる
(このイベントはLuaの関数を実行している間だけ起こる)。
mask
にゼロを設定すればフックが無効になる。
現在のフックとマスク、カウントを得るには、以下の関数を使う。
lua_Hook lua_gethook (lua_State *L); int lua_gethookmask (lua_State *L); int lua_gethookcount (lua_State *L);
フックが呼ばれたとき、
ar
引数の event
フィールドにフックを起動したイベントが格納されている。
さらにlineイベントでは、フィールド currentline
も設定される。
ar
の他のフィールドを得るには、フック内で lua_getinfo
を呼ばなければならない。
returnイベントでは、event
は通常の LUA_HOOKRET
のほかに LUA_HOOKTAILRET
が設定される場合がある。
後者はLuaが終端呼び出しからの復帰をシミュレートしたもので、この場合 lua_getinfo
は役に立たない。
Luaがフックを実行している間、他のフック呼び出しは無効になる。 だからフック内でLuaの関数やチャンクを呼び出した場合、フックは呼ばれずに実行が行われる。
標準ライブラリは、CのAPIを使って直接実装された便利な関数を提供する。
いくつかは言語の本質的なサービスを提供するものであり (例えば type
や getmetatable
)、
残りは「外部の」サービスへのアクセスを提供するものである (例えば I/O)。
また、Lua自身で実装可能であるが、便利さやパフォーマンスのためにCで実装されたものもある (例えば sort
)。
すべてのライブラリは公開されているCのAPIを使って実装されており、独立したCのモジュールで提供されている。 現在、Luaには以下の標準ライブラリがある。
これらのライブラリを使うには、Cのホストプログラムで最初に
luaopen_base
(基本ライブラリ用)、
luaopen_string
(文字列ライブラリ用)、
luaopen_table
(テーブルライブラリ用)、
luaopen_math
(数学ライブラリ用)、
luaopen_io
(I/OライブラリとOSライブラリ用)、
luaopen_debug
(デバッグライブラリ用)
を呼ばなければならない。
これらは lualib.h
に定義されている。
基本ライブラリはLuaへのコアな機能を提供する。 アプリケーションにこのライブラリを含めない場合は、その機能を提供する代わりの実装を用意する必要があるか慎重に調べるべきである。
assert (v [, message])
v
が nil か false であればエラーを発生させる。
そうでなければ、v
を返す。
message
はエラーメッセージを指定する。
省略された場合は "assertion failed!" である。
collectgarbage ([limit])
ガベージコレクションの閾値を指定されたlimit (キロバイト単位) に設定し、カウンタをチェックする。
もし新しい閾値がカウンタよりも小さければ、Luaはすぐにガベージコレクタを走らせる (2.9 を参照)。
limit
が省略された場合は 0 になる (つまり強制的にガベージコレクションを起こす)。
dofile (filename)
stdin
) から読み取って実行する。
dofileはチャンクから返された値をそのまま返す。
エラーが起きた場合は、呼び出し側に伝搬される (つまり保護モードではない)。
最後に保護された関数呼び出しを終了し、error (message [, level])
message
をエラーメッセージとして返す。
関数 error
は戻らない。
level
引数は、エラーメッセージがエラーを指し示す場所を指定する。
レベル1では (デフォルト)、error
関数を呼んだ場所がエラー位置である。
レベル2は error
を呼んだ関数を呼んだ位置を指す。
以下同様である。
_G
_G._G = _G
である。
Lua自身はこの変数を使用しないので、この値を変更しても環境には何の影響もない
(環境を変えるには setfenv
を使う)。
getfenv (f)
f
はLuaの関数か、関数のスタックレベルを示す数値である。
レベル1はgetfenv
を呼んだ関数である。
もし与えられた関数がLuaの関数でなかったり、f
が0の場合は、getfenv
はグローバル環境を返す。
f
のデフォルト値は1である。
もしその環境が "__fenv"
フィールドを持っていたら、環境の代わりにその値を返す。
もしobjectがメタテーブルを持っていなければ nil を返す。
もしobjectのメタテーブルが "__metatable"
フィールドを持っていれば、その値を返す。
そうでなければobjectのメタテーブルを返す。
gcinfo ()
この関数は2つの値を返す。 Luaが使用中の動的メモリの量と、現在のガベージコレクタの閾値である。 共にキロバイト単位である。
ipairs (t)
イテレータ関数と、テーブル t
と、0を返す。
for i,v in ipairs(t) do ... endは (
1,t[1]
)、(2,t[2]
)、…のペアを、最初に値にnilが現れるまで繰り返す。
loadfile (filename)
ファイルをLuaチャンクとして読み込む (実行せずに)。 エラーがなければ、コンパイルされたチャンクが関数として返され、 そうでなければ nil とエラーメッセージが返される。 返された関数の環境はグローバル環境である。
loadlib (libname, funcname)
Cのダイナミックライブラリ libname
をリンクする。
このライブラリの内部で関数 funcname
を検索し、この関数をCの関数として返す。
libname
はCのライブラリの、パスや拡張子を含む完全なファイル名でなければならない。
この関数は ANSI C の範囲ではサポートされていない。
いくつかのプラットフォーム
(Winows, Linux, Solarix, BSD、dlfcn
標準をサポートする他のUnixシステム)
でのみ利用可能である。
loadstring (string [, chunkname])
省略可能な引数 chunkname
は、エラーメッセージやデバッグ情報で使われる名前である。
与えられた文字列をロードして実行するには、以下の慣用句を使う。
assert(loadstring(s))()
next (table [, index])
next
はテーブル内の次のインデックスと、そのインデックスに関連付けられた値を返す。
二番目の引数に nil を渡すと、テーブル内の最初のインデックスとその値が返される。
最後のインデックスで呼び出すか、空のテーブルに対して nil で呼び出すと、
next
は nil を返す。
二番目の引数が省略された場合は nil と解釈される。
Luaにはフィールド定義がない。
テーブル内にフィールドが存在しないのと、nil 値が格納されたフィールドには、何の違いも無い。
ゆえに、next
は nil でない値を持つフィールドのみを考慮する。
インデックスが列挙される順番は、数値のインデックスに対しても、不定である
(数値順にテーブルを巡回するには、数値用の for 文や ipairs
関数を使う)。
テーブルの巡回中に、もし存在していないフィールドに新たに値が割り当てられたら、next
の動作は 未定義 である。
pairs (t)
next
関数とテーブル t
(と、加えて nil) を返す。
for k,v in pairs(t) do ... endはテーブル
t
のすべてのキー・値ペアについて繰り返す。
保護モードで、与えられた引数で f
を呼び出す。
つまり f
の内部で発生したエラーは伝搬されず、
代わりに pcall
がエラーを捕らえ、ステータスコードを返す。
最初の引数はステータスコード (ブーリアン型) で、エラーなしに呼び出しが成功したときは true を返す。
その場合、f
の戻り値もすべて、最初の戻り値に続いて返される。
エラーが起こった場合、pcall
は false とエラーメッセージを返す。
print (e1, e2, ...)
tostring
で文字列に変換してから標準出力 (stdout
) に表示する。
この関数は書式化出力を意図したものではなく、
典型的にはデバッグのために、値を表示する簡単な方法として用意されているだけである。
書式化出力には format
を使う (5.3 を参照)。
rawequal (v1, v2)
v1
と v2
が等しいかどうか調べる。
ブーリアンを返す。
rawget (table, index)
table[index]
の本当の値を得る。
table
はテーブルでなければならない。
index
は nil 以外のどんな値でも良い。
rawset (table, index, value)
table[index]
に value
をセットする。
table
はテーブルでなければならない。
index
は nil 以外のどんな値でも良い。
value
はどんなLuaの値でも良い。
require (packagename)
指定されたパッケージをロードする。
この関数はまず _LOADED
テーブルを検索し、packagename
がすでにロードされているか確認する。
もしロードされていれば、require
は最初にロードされたパッケージを返す。
ロードされていなければ、ファイルを検索してロードする。
グローバル変数 LUA_PATH
が文字列であれば、それは検索パスである。
そうでなければ、require
は環境変数 LUA_PATH
を試してみる。
最後の手段として、定義済みのパス "?;?.lua"
を使う。
パスはセミコロンで区切られた テンプレート の連なりである。
各テンプレートに対して、テンプレート内の疑問符を packagename
に置換し、その結果のファイル名でロードを試みる。
例を挙げると、パスが
"./?.lua;./?.lc;/usr/local/?/?.lua;/lasttry"であれば、
require "mod"
は以下のファイル名を順に試す。
./mod.lua ./mod.lc /usr/local/mod/mod.lua /lasttry
ファイルがロードできたらそこで検索をやめて、ファイルを実行する。
その後、_LOADED
テーブルで、パッケージ名をキーにパッケージからの戻り値が関連付けられ、その値を返す。
パッケージが nil を返した場合 (あるいは何も返さなかった場合)、require
はこの値を true に変える。
パッケージが false を返した場合、require
も false を返す。
この場合、_LOADED
テーブルには false が格納され、
再びファイルの再ロードを試みると、パッケージはロードされていないように振る舞う (つまり、パッケージは再びロードされる)。
ファイルの再ロードを試みてもパッケージはロードされない。
もしロードや実行の途中でエラーがおきたら、あるいはファイルがパス内に見つからなければ、require
はエラーを発する。
ファイルの実行中は、require
はグローバル変数 _REQUIREDNAME
を定義し、パッケージ名を格納する。
ロードされたパッケージは常にグローバル環境内で実行される。
指定された関数で使われる現在の環境を変更する。
f
はLuaの関数か、関数のスタックレベルを指定する数値である。
レベル1は setfenv
を呼び出した関数を示す。
特殊なケースとして、f
に0が与えられると、setfenv
は走行中のスレッドのグローバル環境を変える。
元の環境が "__fenv"
フィールドを持っていると、setfenv
はエラーを発生させる。
setmetatable (table, metatable)
table
のメタテーブルを変更する
(Luaからユーザーデータのメタテーブルを変更することはできない)。
もし metatable
が nil であれば、table
のメタテーブルは除去される。
元のメタテーブルが "__metatable"
フィールドを持っていると、エラーを発する。
tonumber (e [, base])
tonumber
は数値を返す。
そうでなければ nil を返す。
省略可能な引数は数値を解釈する際の基数を指定する。
基数は2から36の整数を指定できる。
10より大きい基数では、`A
´が10を表し、`B
´が11を表し、
以下同様に続き、`Z
´が35を表す (大文字でも小文字でも良い)。
基数が10 (デフォルト) の場合 は、数値に小数部や指数部を付けることができる (2.2.1 を参照)。
他の基数では、符号なしの整数のみを受け付ける。
tostring (e)
format
を使う (5.3 を参照)。
もし e
のメタテーブルが "__tostring"
フィールドを持っていたら、
e
を引数に、その関連付けられた値が呼び出され、その戻り値が結果として使われる。
値の型を文字列で返す。
この関数が返す値は以下のいずれかである。
type (v)
"nil" (という文字列。nil 値ではなく。) "number" "string" "boolean" "table" "function" "thread" "userdata"
unpack (list)
return list[1], list[2], ..., list[n]数値 n はリストの長さであり、
table.getn
関数で定義される。
_VERSION
"Lua 5.0"
である。
xpcall (f, err)
この関数は pcall
に似ているが、エラーハンドラを指定できる点が異なる。
xpcall
は保護モードで f
を呼び出し、
err
をエラーハンドラとして使う。
f
の内部で発生したエラーは伝搬されない。
代わりに、xpcall
がエラーを捕らえ、エラーオブジェクトを引数に err
を呼ぶ。
最初の戻り値はステータスコード (ブーリアン型) で、
エラーが起きなかった場合は true を返す。
その場合、最初の戻り値に続いて f
の戻り値もすべて返される。
エラーが起きた場合、xpcall
は false と err
の戻り値を返す。
コルーチン関連の操作は基本ライブラリのサブライブラリであり、テーブル coroutine
内に置かれている。
コルーチンに関する一般的な説明は 2.10 を参照。
coroutine.create (f)
f
を本体とする新しいコルーチンを作る。
f
はLuaの関数でなければならない。
"thread"
型の新しいコルーチンオブジェクトを返す。
coroutine.resume (co, val1, ...)
コルーチン co
の実行を開始/再開する。
コルーチンを最初にresumeしたとき、その本体の実行が開始される。
引数 val1
, ... は本体の関数に渡される。
コルーチンが中断されていた場合、resume
はそれを再開し、
yield からの戻り値として val1
, ... が渡される。
コルーチンがエラー無く実行されれば、
resume
は true に加えて yield
に渡された値 (コルーチンが中断された場合)、
もしくは本体の関数から返された値 (コルーチンが終了した場合) を返す。
エラーが起きたら、resume
は false とエラーメッセージを返す。
coroutine.status (co)
コルーチン co
の状態を文字列で返す。
"running" (コルーチンは走行中)
"suspended" (コルーチンは yield
の呼び出しで中断されているが、まだ実行中である)
"dead" (コルーチンの本体の関数が終了したか、エラーで停止した)
coroutine.wrap (f)
f
を本体とする新しいコルーチンを作成する。
f
はLuaの関数でなければならない。
coroutine.wrap
は、呼ばれるたびにコルーチンを再開する関数を返す。
関数に渡された引数は resume
に余分に渡される引数と同じ動作をし、
戻り値は resume
から最初のブーリアンを除いた値と同じである。
もしエラーが起きた場合、エラーは伝搬する。
coroutine.yield (val1, ...)
呼ばれたコルーチンの実行を中断する。
コルーチンは、Cの関数やメタメソッド、イテレータを中断することはできない。
yield
に渡された引数は resume
から追加の戻り値として返される。
5.3 - 文字列操作
このライブラリは、検索や部分文字列の抽出、パターンマッチングといった、文字列操作のための一般的な機能を提供する。
Luaの文字列のインデックス付けは、最初の文字が1の位置である (Cのように0ではない)。
文字列の末尾から逆方向にマイナス値で指定することもできる。
つまり、最後の文字は -1 の位置で示される。
文字列ライブラリはすべて、テーブル string
内の関数として提供される。
string.byte (s [, i])
s
の i
番目の文字の内部コードの数値を返す。
インデックスが範囲外の場合は nil を返す。
もし i
が省略された場合、1とみなされる。
i
には負の値も使える。
文字コードの数値は、プラットフォームを超えての可搬性がないことに注意。
string.char (i1, i2, ...)
文字コードの数値は、プラットフォームを超えての可搬性がないことに注意。
string.dump (function)
指定された関数のバイナリ表現を返す。
loadstring
にこの文字列を渡すことで、関数のコピーを作ることができる。
function
は上位値を持たないLua関数でなければならない。
string.find (s, pattern [, init [, plain]])
s
内で pattern
の最初の マッチ を探す。
もし見つかれば、find
は s
内でこのパターンがマッチした開始位置と終了位置のインデックスを返す。
そうでなければ nil を返す。
もしパターン内にキャプチャが指定されていれば (下の string.gsub
を参照)、
キャプチャされた文字列が追加の引数として返される。
三番目の省略可能な引数 init
は検索開始位置を指定し、デフォルト値は1で、負の値も使える。
四番目の省略可能な引数 plain
に true が指定されると、
パターンマッチング機能はオフになり、
pattern
中の「魔法の」文字は無くなって、ただの「部分文字列を検索する」操作になる。
plain
を与える場合は init
も与えなければならないことに注意。
string.len (s)
""
の長さは0である。
文字列中のゼロも数えるので、"a\000b\000c"
の長さは5である。
string.lower (s)
string.rep (s, n)
s
のコピーを n
個連結した文字列を返す。
string.sub (s, i [, j])
s
の、位置 i
から位置 j
までの部分文字列を返す。
i
にも j
にも、負の値を使える。
j
が省略されたときは -1 とみなされる (つまり文字列の長さと同じ)。
特に、string.sub(s,1,j)
は s
の先頭から j
文字を取り出し、
string.sub(s, -i)
は s
の最後の i
文字を取り出す。
string.upper (s)
最初の引数 (文字列でなければならない) で指定された記述に従い、残りの可変個の引数を書式化して返す。
書式文字列は標準C関数のprintfファミリーと同じルールに従う。
ただし、
string.format (formatstring, e1, e2, ...)
*
、l
、L
、n
、p
、h
はサポートされてなくて、追加の q
がある点だけが異なる。
q
オプションは、Luaインタプリタで安全に読み戻せる適切な形式の文字列に書式化する。
その文字列はダブルクォートの間に書かれ、
文字列中のダブルクォート、改行、バックスラッシュは正しくエスケープされる。
例えば、
string.format('%q', 'a string with "quotes" and \n new line')は次のような文字列を生成する。
"a string with \"quotes\" and \ new line"
c
、d
、E
、e
、f
,
g
、G
、i
、o
、u
,
X
、x
はすべて数値の引数を期待し、
q
と s
は文字列を期待する。
*
修飾子は適当な書式文字列を作ることでシミュレートできる。
例えば、"%*g"
は "%"..width.."g"
のように書けば良い。
%s
で書式化される文字列は、途中にゼロを含んではいけない。
string.gfind (s, pat)
呼ばれるたびに文字列 s
からパターン pat
でキャプチャされた部分を次々と返すような、イテレータ関数を返す。
pat
にキャプチャが指定されていなければ、それぞれの呼び出しごとに、マッチした文字列全体を返す。
例えば、以下のループでは
s = "hello world from Lua" for w in string.gfind(s, "%a+") do print(w) end文字列
s
のすべての単語について繰り返し、それぞれを別々の行に出力する。
次の例は、与えられた文字列から key=value
のペアを集めてテーブルへ入れる。
t = {} s = "from=world, to=Lua" for k, v in string.gfind(s, "(%w+)=(%w+)") do t[k] = v end
string.gsub (s, pat, repl [, n])
pat
をすべて repl
によって指定された置換文字列に置き換えた s
のコピーを返す。
gsub
は二番目の値として、置換が行われた回数も返す。
repl
が文字列であれば、その値が置換に使われる。
repl
内に現れる %
n は (n は1から9)、
n 番目にキャプチャされた部分文字列を表す (以下を見よ)。
repl
が関数であれば、マッチが現れるたびにこの関数が呼ばれる。
関数にはキャプチャされた部分文字列が順番にすべて渡される。
パターンにキャプチャが指定されていなければ、マッチした全体が唯一の引数として渡される。
この関数から返された文字列が、置換文字列として使われる。
関数の戻り値が文字列でなければ、空文字列に置換される。
省略可能な最後の引数 n
は置換が行われる最大回数を制限する。
例えば、n
が1なら最初に現れる pat
だけが置換される。
いくつか例を示す。
x = string.gsub("hello world", "(%w+)", "%1 %1") --> x="hello hello world world" x = string.gsub("hello world", "(%w+)", "%1 %1", 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 loadstring(s)() end) --> x="4+5 = 9" local t = {name="lua", version="5.0"} x = string.gsub("$name_$version.tar.gz", "%$(%w+)", function (v) return t[v] end) --> x="lua_5.0.tar.gz"
文字クラス は文字の集合を表す。 以下の組み合わせを文字クラスの指定に使うことができる。
^$()%.[]*+-?
以外の文字)
--- 文字 x それ自身を表す。
.
--- (ドット) すべての文字を表す。
%a
--- すべてのletterを表す。
%c
--- すべての制御文字を表す。
%d
--- すべての数字を表す。
%l
--- すべての小文字を表す。
%p
--- すべての区切り記号を表す。
%s
--- すべての空白文字を表す。
%u
--- すべての大文字を表す。
%w
--- すべての英数文字を表す。
%x
--- すべての十六進数字を表す。
%z
--- 0として表現される文字を表す。
%x
(x は英数文字以外) ---
文字 x 自身を表す。
これは魔法の文字をエスケープする標準的な方法である。
いかなる区切り文字 (魔法の文字でなくても) は前に `%´ を付けることでそれ自身を表すことができる。
[set]
---
set 内のすべての文字の和からなるクラスを表す。
終わりの文字と `-
´ で繋げることで、文字の範囲を表す。
上で挙げた %
x 形式のすべてのクラスも、set の中で使うことができる。
それ以外の set 内の文字は、それ自身を表す。
例えば、[%w_]
(または [_%w]
) は、すべての英数にアンダースコアを加えたものを表す。
[0-7]
は八進数字を表し、
[0-7%l%-]
は八進数字と小文字と `-
´ を表す。
範囲とクラスの相互作用は未定義である。
つまり、[%a-z]
や [a-%%]
のようなパターンは意味を持たない。
[^set]
---
set の補集合を表す。
set の内容は上で説明したものと同じである。
%a
、%c
など) はすべて、対応する大文字は補集合を表す。
例えば %S
は空白以外のすべての文字を表す。
文字、空白、その他の文字のグループの定義については、現在のロケールに依存する。
特に、クラス [a-z]
は %l
と等価ではないかもしれない。
可搬性のためには後者の形式の方が望ましい。
パターンの要素 は以下のいずれかである。
*
´ が続いたもの。
そのクラスの文字の0回以上の繰り返しにマッチする。
この繰り返し要素は、可能な限り長いシーケンスにマッチする。
+
´ が続いたもの。
そのクラスの文字の1回以上の繰り返しにマッチする。
この繰り返し要素は、可能な限り長いシーケンスにマッチする。
-
´ が続いたもの。
そのクラスの文字の0回以上の繰り返しにマッチする。
`*
´ と異なり、この繰り返し要素は可能な限り 短い シーケンスにマッチする。
?
´ が続いたもの。
そのクラスの文字の0回または1回の出現にマッチする。
%n
(n は1から9)。
これは、n 番目にキャプチャされた文字列にマッチするような要素である (下の説明を参照)。
%bxy
(x と y は異なる文字)。
これは x で始まって y で終わる文字列にマッチするような要素である。
x と y は 対応が取れる。
つまり、文字列を左から右に読んでいって、
x が現れるたびにカウントを +1 し、y では -1 したとき、
最後の y はカウントが0になる最初の y である。
例えば、要素 %b()
はカッコの対応が取れた式にマッチする。
pattern はパターン要素の列である。
パターンの最初に現れる `^
´ は対象文字列の先頭にマッチを固定する。
パターンの最後に現れる `$
´ は対象文字列の最後にマッチを固定する。
他の位置では、`^
´ や `$
´ は特別な意味を持たず、それ自身を表す。
パターンはカッコで囲まれたサブパターンを持つことができ、それらは キャプチャ と呼ばれる。
マッチが成功したとき、対象文字列の中でキャプチャにマッチした部分が保存 (キャプチャ) され、後で使うことができる。
キャプチャはその左カッコによって番号付けされる。
例えば、パターン "(a*(.)%w(%s*))"
では、
"a*(.)%w(%s*)"
にマッチする部分が最初のキャプチャとして保存され (だから1番になる)、
.
にマッチする文字が2番にキャプチャされ、
%s*
にマッチする部分が3番になる。
特殊なケースとして、空キャプチャ ()
は文字列の現在位置 (数値) をキャプチャする。
例えば、文字列 "flaaap"
にパターン "()aa()"
を適用すると、
2つのキャプチャ3と5を得られる。
パターンには途中にゼロを含むことができない。代わりに %z
を使う。
5.4 - テーブル操作
このライブラリはテーブル操作のための一般的な機能を提供する。
テーブル table
内にすべての関数が提供される。
テーブルライブラリのほとんどの関数は、テーブルが配列やリストを表現しているとみなす。 これらの関数では、重要な概念は配列の 長さ である。 この長さを指定するには3つの方法がある。
"n"
---
テーブルがフィールド "n"
を数値として持つ場合は、その値が長さとみなされる。
setn
---
table.setn
関数を呼ぶことで、明示的にテーブルの長さを設定する。
table.getn
と table.setn
関数の説明を参照。
table.concat (table [, sep [, i [, j]]])
table[i]..sep..table[i+1] ... sep..table[j]
を返す。
sep
のデフォルト値は空文字列で、
i
のデフォルト値は1、
j
のデフォルト値はテーブルの長さである。
i
が j
よりも大きい場合は空文字列を返す。
table.foreach (table, f)
table
のすべての要素について f
を実行する。
各要素に対して、そのインデックスと対応する値が f
に渡される。
f
が nil 以外の値を返したらループを中断し、
foreach
の最後の値としてその値が返される。
テーブル巡回に関するさらなる情報は next
関数を参照。
table.foreachi (table, f)
table
の数値インデックスについて f
を実行する。
各インデックスについて、そのインデックスと対応する値が f
に渡される。
インデックスは1から n
まで順番に辿る。
n
はテーブルの長さである (5.4 を参照)。
f
が nil 以外の値を返したらループを中断し、
foreachi
の結果としてその値が返される。
リストと見なしたテーブルの長さを返す。
もしテーブルが table.getn (table)
n
フィールドを数値で持っていたら、その値がテーブルの長さである。
そうでなくて、このテーブルに対して以前に table.setn
が呼ばれていたら、そのときの値が返される。
いずれでもなければ、nil 値があらわれる最初の整数インデックスよりも1小さい値がその長さである。
table.sort (table [, comp])
table[1]
から table[n]
までのテーブル要素を、指定された順序で その場で ソートする。
n
はテーブルの長さである (5.4 を参照)。
comp
を与える場合、それは関数でなくてはならず、テーブルの要素を2つ受け取り、最初の要素が二番目よりも小さいときにtrueを返さなければならない
(ソート後、not comp(a[i+1],a[i])
が true になる)。
comp
が与えられなければ、標準のLuaの演算子 <
が代わりに使われる。
ソートのアルゴリズムは安定でない。 つまり、指定された順序において等しいと考えられる要素は、ソートによってその相対位置が変わるかもしれない。
table.insert (table, [pos,] value)
table
の位置 pos
に要素 value
を挿入する。
空きスペースが必要なら、他の要素を上にずらす。
pos
のデフォルト値は n+1
である。
n
はテーブルの長さである (5.4 を参照)。
table.insert(t,x)
の呼び出しは、テーブル t
の最後に x
を挿入する。
この関数は table.setn(table, n+1)
を呼んでテーブルの長さも更新する。
table.remove (table [, pos])
table
から位置 pos
の要素を取り除き、
必要なら他の要素を下にずらして空白を埋める。
取り除かれた要素の値が返される。
pos
のデフォルト値は n
である。
n
はテーブルの長さである (5.4 を参照)。
table.remove(t)
の呼び出しは、テーブル t
の最後の要素を取り除く。
kの関数は table.setn(table, n-1)
を呼んでテーブルの長さも更新する。
table.setn (table, n)
テーブルの長さを更新する。
テーブルがフィールド "n"
を数値で持っていれば、その値が n
に変わる。
そうでなければ、内部状態を更新し、table.getn(table)
が n
を返すようにする。
このライブラリは標準C数学ライブラリのほとんどの関数へのインタフェイスである
(いくつかは異なった名前を持つ)。
math
テーブルの中にすべての関数が提供される。
加えて、累乗の二項演算子 ^
のためのグローバルな __pow
も登録される。
すなわち x^y
は xy を返す。
このライブラリは以下の関数を提供する。
math.abs math.acos math.asin math.atan math.atan2 math.ceil math.cos math.deg math.exp math.floor math.log math.log10 math.max math.min math.mod math.pow math.rad math.sin math.sqrt math.tan math.frexp math.ldexp math.random math.randomseed加えて、変数
math.pi
も提供される。
これらのほとんどは、Cライブラリの対応する関数へのインタフェイスである。
すべての三角関数はラジアンを使う (前バージョンのLuaは度を使っていた)。
関数 math.deg
と math.rad
はラジアンと度を変換する。
関数 math.max
は引数の中の最大値を返す。
同様に math.min
は最小値を求める。
共に1つ、2つ、あるいはもっとたくさんの引数を渡すことができる。
関数 math.random
と math.randomseed
は ANSI C で提供される単純なランダム生成関数 rand
と srand
へのインタフェイスである
(統計的な性質は保証されない)。
引数無しで呼ばれると、math.random
は [0,1) の範囲の実数の疑似乱数を返す。
数値 n を渡すと、math.random
は [1,n] の範囲の整数の疑似乱数を返す。
2つの引数 l と u を渡して呼んだときは、
math.random
は [l,u] の範囲の整数の疑似乱数を返す。
math.randomseed
関数は疑似乱数発生器の「シード値」を設定する。
同じシード値からは同じ数列が生成される。
I/Oライブラリは2つの異なったスタイルのファイル操作を提供する。 ひとつめは暗黙のファイルディスクリプタを使うもので、 それらはデフォルト入力ファイルとデフォルト出力ファイルに対して作用し、 すべての入出力操作はデフォルトファイルを通して行われる。 ふたつめのスタイルでは明示的なファイルディスクリプタを用いる。
暗黙のファイルディスクリプタを使う場合は、すべての操作はテーブル io
で提供される。
明示的なファイルディスクリプタを使う場合は、
すべての操作は io.open
が返すファイルディスクリプタのメソッドとして提供される。
テーブル io
は、
Cで使われる意味と同じの3つの定義済みファイルディスクリプタ
io.stdin
、io.stdout
、io.stderr
も提供する。
ファイルハンドルは、I/Oライブラリが作る独自のメタテーブルを備えた、ファイルストリーム (FILE*
) を持つユーザーデータである。
例外なく、すべてのI/O関数は失敗時に nil (および二番目の戻り値としてエラーメッセージ) を返し、 成功時は nil 以外の何らかの値を返す。
io.close ([file])
file:close()
と等価である。
file
が省略されると、デフォルト出力ファイルを閉じる。
io.flush ()
デフォルト出力ファイルに対する file:flush
と等価である。
io.input ([file])
ファイル名を与えて呼ぶと、その名前のファイルを (テキストモードで) 開き、 そのハンドルをデフォルト入力ファイルに設定する。 ファイルハンドルを与えて呼ぶと、単純にそのファイルハンドルがデフォルト入力ファイルに設定される。 引数無しで呼ぶと、現在のデフォルト入力ファイルを返す。
エラーが起きた場合、この関数はエラーコードを返す変わりにエラーを発する。
io.lines ([filename])
指定されたファイル名を読み込みモードで開き、 呼ばれるたびにファイルから1行ずつ返すイテレータ関数を返す。 つまり、
for line in io.lines(filename) do ... endはファイルのすべての行について繰り返す。 イテレータ関数は、ファイルの終わりを検出すると nil を返し (ループを終えるため)、自動的にファイルを閉じる。
io.lines()
(ファイル名を渡さない) は io.input():lines()
と等価である。
すなわち、デフォルト入力ファイルの各行について繰り返す。
io.open (filename [, mode])
この関数は mode
で指定されたモードでファイルを開く。
新しいファイルハンドルを返すか、エラーの場合は nil とエラーメッセージを返す。
mode
文字列は以下のいずれかである。
mode
文字列は最後に b
も付けることができ、
システムによってはバイナリモードでファイルを開くために必要である。
この文字列は標準Cの関数 fopen
で使われるのと同じである。
io.output ([file])
io.input
と同じであるが、デフォルト出力ファイルに対する操作である。
io.read (format1, ...)
io.input():read
と等価である。
io.tmpfile ()
テンポラリファイルのハンドルを返す。 このファイルは更新モードでオープンされ、プログラムの終了時に自動的に削除される。
io.type (obj)
obj
が有効なファイルハンドルかどうかチェックする。
obj
がオープンされているファイルハンドルなら、文字列 "file" を返す。
obj
がクローズされたファイルハンドルなら、文字列 "closed file" を返す。
obj
がファイルハンドルでなければ nil を返す。
io.write (value1, ...)
io.output():write
と等価である。
file:close ()
file
を閉じる。
file:flush ()
file
に書き込まれたデータを保存する。
file:lines ()
呼ばれるたびにファイルから新しい行を返すイテレータ関数を返す。 つまり、
for line in file:lines() do ... endはファイルのすべての行に対して繰り返す (
io.lines
と異なり、この関数はループの終わりでファイルを閉じない)。
file:read (format1, ...)
何を読むかを指定する書式に従って、ファイル file
から読み込む。
各書式について、読み込んだ文字を文字列 (または数値) として返し、
指定された書式でデータを読めなければ nil を返す。
書式を指定せずに呼ばれた場合は、次の行全体を読むデフォルトの書式が使われる (以下を参照)。
利用可能なフォーマットは次の通り。
file:seek ([whence] [, offset])
ファイルの先頭から計ったファイル位置を設定/取得する。
位置は文字列 whence
で指定された基準位置に offset
を加えた値で示す。
whence
は以下のいずれかである。
seek
はファイル先頭からのバイト数で最終的なファイル位置を返す。
この関数が失敗すると nil とエラー文字列を返す。
whence
のデフォルト値は "cur"
で、
offset
は0である。
つまり、file:seek()
の呼び出しは、何も変化させずに、現在の位置を返す。
file:seek("set")
はファイルの先頭に位置を変更する (そして0を返す)。
file:seek("end")
はファイルの終わりに位置を変更し、ファイルの長さを返す。
file:write (value1, ...)
引数のそれぞれの値をファイルハンドル file
に書き込む。
引数は文字列か数字でなければならない。
それ以外の値を書き込むには、
write
の前に tostring
か string.format
を使う。
このライブラリはテーブル os
を通して提供される。
os.clock ()
プログラムが使ったCPU時間の概算値を秒で返す。
os.date ([format [, time]])
与えられた文字列 format
に従って書式化した日付と時刻を含む文字列、またはテーブルを返す。
time
引数が存在すれば、それが書式化される時刻となる
(この値の説明は os.time
関数を参照)。
そうでなければ、date
は現在時刻を書式化する。
format
が `!
´ で始まっていたら、
日付は世界時 (Universal Time) で書式化される。
このオプション文字の後、
format
が *t
であれば、
date
は以下のフィールドを持つテーブルを返す。
year
(4桁の数値)
month
(1--12)
day
(1--31)
hour
(0--23)
min
(0--59)
sec
(0--61)
wday
(曜日、日曜日が1)
yday
(1月1日から数えた日数)
isdst
(夏時間を示すフラグ、ブーリアン)
format
が *t
でなければ、
date
は日付を文字列として返す。
Cの関数 strftime
と同じルールに従って書式化される。
引数なしで呼ばれた場合、
date
はホストシステムと現在のロケールに依存する一般的な日付と時刻の表現を返す。
(つまり、os.date()
は os.date("%c")
と等価である)。
os.difftime (t2, t1)
時刻 t1
から時刻 t2
までの秒数を返す。
POSIX や Windows、その他のいくつかのシステムでは、
この値は t2
-t1
に等しい。
os.execute (command)
この関数はCの関数 system
と等価である。
command
はOSのシェルによって実行されるコマンドを渡す。
システムに依存するステータスコードを返す。
os.exit ([code])
省略可能な code
でCの関数 exit
を呼んでホストプログラムを終了させる。
code
のデフォルト値は成功を表すコードである。
os.getenv (varname)
プロセスの環境変数 varname
の値を返す。
変数が未定義なら nil を返す。
os.remove (filename)
指定された名前のファイルを消す。 この関数が失敗した場合は nil とエラーメッセージを返す。
os.rename (oldname, newname)
oldname
という名前のファイルを newname
にリネームする。
この関数が失敗した場合は nil とエラーメッセージを返す。
os.setlocale (locale [, category])
プログラムの現在のロケールを設定する。
locale
はロケールを表す文字列である。
category
は変更したいカテゴリを表す省略可能な文字列で、以下のいずれかである。
"all"
, "collate"
, "ctype"
,
"monetary"
, "numeric"
, or "time"
。
デフォルトのカテゴリは "all"
である。
この関数は新しいロケールの名前を返す。
あるいは要求が受け付けられなければ nil を返す。
os.time ([table])
引数無しで呼ばれたときは現在の時刻を返し、
引数がある場合は、与えられたテーブルで指定された日付と時刻を表す時刻を返す。
このテーブルはフィールド year
, month
, and day
を持たなければならず、
省略可能だがフィールド hour
, min
, sec
, and isdst
があっても良い
(これらのフィールドの説明は os.date
関数を参照).
戻り値は数値であり、その意味はシステムに依存する。
Posix や Windows、およびいくつかのシステムでは、
特定の開始時刻 (「エポック」)からの経過時間を秒で表している。
それ以外のシステムでは、その意味は不明であり、
time
の戻り値は
date
と difftime
の引数としてのみ使うことができる。
os.tmpname ()
テンポラリファイルとして使えるファイル名を返す。 このファイルは使う前に明示的にオープンする必要があり、 要らなくなったら削さなければならない。
この関数はCの関数 tmpnam
と等価であり、
多くの人々 (といくつかのコンパイラでさえも!) が、これを使わないようアドバイスしている。
なぜなら、この関数を呼んでからファイルを開くまでの間に、
他のプロセスがその名前のファイルを作ってしまう可能性があるためである。
debug
ライブラリはLuaプログラムへのデバッグインタフェイスの機能を提供する。
このライブラリを使うときは注意すべきである。
ここで提供される関数はデバッグやそれに似たプロファイリングのようなタスクにのみ使うべきである。
普通のプログラミングツールとしてこれらを使う誘惑に抵抗するように。
これらは非常に遅い。
さらに言えば、setlocal
や getlocal
はローカル変数のプライバシーを侵害し、安全なコードを危うくする恐れがある。
このライブラリのすべての関数は debug
テーブル内に提供される。
debug.debug ()
ユーザーとの対話モードに入り、ユーザーが入力した文字列を実行する。
単純なコマンドや他のデバッグ機能を使って、
ユーザーはグローバル変数やローカル変数を調べたり値を変更したり式を評価したりその他ができる。
ユーザーが cont
だけの行を入力すると対話モードを終えて実行を継続する。
debug.debug
で実行されるコマンドは、
どの関数のレキシカルスコープにも入っていないので、
ローカル変数へは直接アクセスできないことに注意。
debug.gethook ()
現在のフック関数、フックマスク、フックカウント (debug.sethook
関数で設定されたもの) を返す。
debug.getinfo (function [, what])
この関数は関数に関する情報をテーブルに入れて返す。
関数を直接指定するか数値を指定することができる。
数値は、関数が走っているコールスタックのレベルを意味し、
レベル0は現在の関数 (getinfo
自身)、
レベル1は getinfo
を呼び出した関数で、以下同様。
function
がアクティブな関数の数よりも大きい数値であれば getinfo
は nil を返す。
what
はどのフィールドを埋めるかを記述する文字列で、
戻り値のテーブルには lua_getinfo
から返されるフィールドがすべて含まれている。
what
のデフォルト値では有効なすべての情報を取得する。
もし存在すれば、`f
´ オプションは func
という名前のフィールドにその関数自身を入れる。
例えば、式 debug.getinfo(1,"n").name
は現在の関数の名前を返す (もし適当な名前があれば)。
debug.getinfo(print)
は print
関数に関するすべての利用可能な情報を持つテーブルを返す。
debug.getlocal (level, local)
スタックレベル level
の関数の、インデックス local
のローカル変数の、名前と値を返す。
最初の引数かローカル変数がインデックス1で、以下同様に最後の有効なローカル変数まで続く。
もし指定されたインデックスのローカル変数がなければ nil を返し、
level
が範囲外であればエラーを発する
(debug.getinfo
を使ってレベルが有効かどうかチェックできる)。
debug.getupvalue (func, up)
関数 func
の、インデックス up
の上位値の、名前と値を返す。
指定されたインデックスの上位値が存在しなければ nil を返す。
debug.setlocal (level, local, value)
スタックレベル level
の関数の、インデックス local
のローカル変数に、値 value
を格納する。
指定されたインデックスのローカル変数が存在しなければ nil を返し、
level
が範囲外であればエラーを発する
(debug.getinfo
を使ってレベルが有効かどうかチェックできる)。
debug.setupvalue (func, up, value)
関数 func
の、インデックス up
の上位値に、値 value
を格納する。
指定されたインデックスの上位値が存在しなければ nil を返す。
debug.sethook (hook, mask [, count])
指定された関数をフックに設定する。
文字列 mask
と数値 count
は、いつフックが呼ばれるかを記述する。
文字列maskは以下の文字からなる。
"c"
フックはLuaが関数を呼ぶたびに呼ばれる。
"r"
フックはLuaが関数から戻るたびに呼ばれる。
"l"
フックはLuaがコードの新しい行に入るたびに呼ばれる。
count
がゼロでなければ、フックは count
命令が実行されるたびに、その直後に呼ばれる。
引数なしで呼ぶとフックは無効になる。
フックが呼ばれたとき、最初の引数は常に、フックを起動したイベントを示す以下のいずれかの文字列である。
"call"
, "return"
"tail return"
,
"line"
, "count"
。
さらにlineイベントの場合は二番目の引数に新しい行番号が得られる。
"tail return"
を除いて、
フックの内部でレベル2の getinfo
を呼べば、実行中の関数に関する情報をもっと得られる
(レベル0は getinfo
関数自身で、レベル1はフック関数である)。
"tail return"
はLuaが復帰をシミュレートしているだけであり、
getinfo
は正しくないデータを返すだろう。
debug.traceback ([message])
コールスタックのトレースバックを出力した文字列を返す。
省略可能な message
文字列は、トレースバックの最初に付け加えられる。
この関数は典型的には、より良いエラーメッセージを生成するために xpcall
と一緒に使われる。
LuaはCのホストプログラムに組み込まれる拡張言語としてデザインされたにも関わらず、
スタンドアロンの言語としてもよく使われる。
スタンドアロンの言語としてのLuaインタプリタは、単純に lua
と呼ばれ、
標準のディストリビューションと共に提供されている。
スタンドアロンのインタプリタはすべての標準ライブラリとリフレキシブデバッグインタフェイスを含んでいる。
使い方は以下の通り。
lua [options] [script [args]]オプションは以下の通り。
-
ファイルの代わりに stdin
から実行する。
-e
stat 文字列 stat を実行する。
-l
file file を "requires" する。
-i
script を実行した後、対話モードに入る。
-v
バージョン情報を出力する。
--
オプションの処理を止める。
lua
は指定された script に args を渡して実行する。
引数なしで呼ばれた場合、
stdin
が端末であれば lua -v -i
、
そうでなければ lua -
として振る舞う。
どの引数も適用される前に、
インタプリタは環境変数 LUA_INIT
を調べる。
その書式が @filename であれば、そのファイルを実行する。
そうでなければ、その文字列自身を実行する。
-i
以外のすべてのオプションは順番に処理される。
例えば、以下のようなコマンドは
$ lua -e'a=1' -e 'print(a)' script.luaまず
a
に1を代入し、それから a
を表示し、最後にファイル script.lua
を実行する
(ここで、$
はシェルプロンプトである。キミのシェルプロンプトは違うかもしれない)。
スクリプトを実行する前に、lua
はコマンドライン引数を arg
という名前のグローバルなテーブルに格納する。
スクリプト名がインデックス0に格納され、
最初のhきすうがスクリプト名の後のインデックス1に格納され、以下同様である。
フィールド n
はスクリプト名の後の引数の数を持つ。
スクリプト名の前のすべての引数 (つまり、インタプリタの名前やオプション) は負のインデックスに割り当てられる。
つまり、次のような場合
$ lua -la.lua b.lua t1 t2インタプリタはまずファイル
a.lua
を実行し、
次に以下のようなテーブルを作る。
arg = { [-2] = "lua", [-1] = "-la.lua", [0] = "b.lua", [1] = "t1", [2] = "t2"; n = 2 }そして最後にファイル
b.lua
を実行する。
対話モードでは、不完全な文を書いたときは、それが完全な文になるまで待つ。
グローバル変数 _PROMPT
が文字列として定義されていれば、
その値がプロンプトに使われる。
つまり、プロンプトはコマンドラインから直に変更できる。
$ lua -e"_PROMPT='myprompt> '" -i(外側のクォート対はシェルのための、内側はLuaのためのもの。) また、
_PROMPT
に代入することで、Luaのプログラムからも変更できる。
対話モードに入るには -i
が要ることに注意。
そうでなければ、プログラムは _PROMPT
に代入した直後に終わるであろう。
Unixシステムでは、Luaスクリプトは
chmod +x
を使い、以下のような #!
形式を使って、
実行可能なプログラムにすることができる。
#!/usr/local/bin/lua(もちろん、キミのマシンではLuaインタプリタは違う場所にあるかもしれない。 もし
PATH
の通るところに lua
があれば、
#!/usr/bin/env luaがより移植性の高い解決法である)。
LuaチームはTecgrafがLuaをサポートし続けてくれたことに大きな感謝を捧げる。 我々はTecgrafの全員に、特にグループのリーダーである Marcelo Gattass に感謝する。 いくつかの名前を忘れている可能性もあるが、 我々はLuaに関するサポート、貢献、普及を行ってくれた以下のひとりひとりにも感謝する。 Alan Watson. André Clinio, André Costa, Antonio Scuri, Asko Kauppi, Bret Mogilefsky, Cameron Laird, Carlos Cassino, Carlos Henrique Levy, Claudio Terra, David Jeske, Ed Ferguson, Edgar Toernig, Erik Hougaard, Jim Mathies, John Belmonte, John Passaniti, John Roll, Jon Erickson, Jon Kleiser, Mark Ian Barlow, Nick Trout, Noemi Rodriguez, Norman Ramsey, Philippe Lhoste, Renata Ratton, Renato Borges, Renato Cerqueira, Reuben Thomas, Stephan Herrmann, Steve Dekorte, Thatcher Ulrich, Tomás Gorham, Vincent Penquerc'h. ありがとう!
Lua 5.0 はメジャーリリースである。 以前のバージョン、Lua 4.0 とはいくつか非互換な点がある。
{a,b,f()}
のような) では、
そのすべての戻り値がリストに追加される。
for k,v in t
(t
はテーブル) は非推奨になった (まだ使えるけれども)。
代わりに for k,v in pairs(t)
を使う。
[[...]]
形式の文字列リテラルが改行で始まっていたら、その改行は無視されるようになった。
%var
形式の上位値は廃止された。
代わりに外部ローカル変数を使う。
compat.lua
) も用意されてはいる。
compat.lua
) を使うと、これらは度で動作するようになる。
call
関数が非推奨になった。
保護しない呼び出しには call(f, tab)
の代わりに f(unpack(tab))
を使う。
または保護された呼び出しでは新しい pcall
関数を使う。
dofile
はエラーを処理せず、単にそれを伝搬するようになった。
dostring
は非推奨になった。代わりに loadstring
を使う。
read
関数のオプション *w
は廃止された。
format
関数のオプション %n$
は廃止された。
lua_open
はスタックの長さを取らなくなった (スタックは動的に確保される)。
lua_pushuserdata
は非推奨になった。
代わりに lua_newuserdata
か lua_pushlightuserdata
を使う。
chunk ::= {stat [`;´]}
block ::= chunk
stat ::= varlist1 `=´ explist1 | functioncall | do block end | while exp do block end | repeat block until exp | if exp then block {elseif exp then block} [else block] end | return [explist1] | break | for Name `=´ exp `,´ exp [`,´ exp] do block end | for Name {`,´ Name} in explist1 do block end | function funcname funcbody | local function Name funcbody | local namelist [init]
funcname ::= Name {`.´ Name} [`:´ Name]
varlist1 ::= var {`,´ var}
var ::= Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name
namelist ::= Name {`,´ Name}
init ::= `=´ explist1
explist1 ::= {exp `,´} exp
exp ::= nil | false | true | Number | Literal | function | prefixexp | tableconstructor | exp binop exp | unop exp
prefixexp ::= var | functioncall | `(´ exp `)´
functioncall ::= prefixexp args | prefixexp `:´ Name args
args ::= `(´ [explist1] `)´ | tableconstructor | Literal
function ::= function funcbody
funcbody ::= `(´ [parlist1] `)´ block end
parlist1 ::= Name {`,´ Name} [`,´ `...´] | `...´
tableconstructor ::= `{´ [fieldlist] `}´ fieldlist ::= field {fieldsep field} [fieldsep] field ::= `[´ exp `]´ `=´ exp | name `=´ exp | exp fieldsep ::= `,´ | `;´
binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `..´ | `<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ | and | or
unop ::= `-´ | not