プログラミング言語 Lua 4.0 レファレンスマニュアル

Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes

2000年10月31日

Copyright © 1994-2000 TeCGraf, PUC-Rio. All rights reserved.

日本語訳 池田 徹志、上野 豊*  2001年4月4日

*) 訳に関する問い合わせは、ueno@etl.go.jp 産業技術総合研究所まで

1. はじめに

Luaは汎用の処理記述型のプログラミングを支援するために設計された拡張プ ログラム言語である.Luaは軽くかつ強力な構築言語が必要なプログラムのた めに作られた.

LuaはライブラリとしてC言語で実装されている.拡張言語となるために,Lua には main() プログラムをもっていない.すなわち,ホストとなる主プログラ ムに 組み込まれる 組み込みプログラムとなる.主プログラムは Luaによって書かれたプログラムを実行するための関数を呼ぶことができ,Lua で記述されたデータの読み書きができ,C 言語の関数を Lua から呼べる様に 登録することができる.C 言語の関数を利用すれば,様々な領域の広い問題に 対処するため Lua の機能を拡張でき,文法的な枠組みを共有する一群の拡張 言語を作ってゆくことができる.

Lua は自由に配布されるソフトウェアであり,著作権に関する文書に書かれて いるように,無保証で提供される.この文書に書かれた内容の実装は下記の URLから 取得する事ができる


   http://www.tecgraf.puc-rio.br/lua/
   ftp://ftp.tecgraf.puc-rio.br/pub/lua/lua.tar.gz

他のレファレンスマニュアルと同様に,この文書も無味乾燥である.Lua の設 計の背景にある議論については,以下の文献を参照されたい.これらの文献も 上記の URL から得ることができる.

2. 動作環境とチャンク

Luaではすべての式は一つの 大域環境 (global environment)で実行され る1. この環境は Luaを組み込んでいるプログラムが lua_open()を呼び 出して初期化を行ってから lua_close() を呼ぶか,プログラムが終了 するまでの間有効である.必要に応じて,複数の独立した大域環境を使い分け ることも可能である(5節参照).

大域環境は Lua のプログラムまたは Lua を組み込んでいるプログラムから操 作することができる.Lua を実装しているライブラリの API 関数を使うこと で,組み込んでいるプログラムからも大域変数を読み書きできる.

Lua では大域変数を宣言する必要はない.明示的に局所変数と定義しない限り 大域変数になる(4.5.5節参照).最初の代入が行われるまでは変数の値は nil である(この値は変えることも可能である.4.7節参照). 大域変数の名前と値を管理するのに特定のテーブルが用いられる (テーブルの説明は2節参照).

Luaの実行単位は チャンクと呼ばれる.チャンクは逐次的に実行される文 の系列である.文の最後にはセミコロンがあっても良い.


       chunk ::= {stat [';'}]

文に関しては 4.3節 で解説する(上記は拡張 BNF 記法で書かれている. {a} は 0 回以上の a の繰り返し, [a] a の 任意の出現, a+ は 1 回以上の a の繰り返しである).

チャンクはファイルまたは Lua を組み込むプログラム中の文字列の形で保存 される.チャンクが実行されるときは,まずすべてのプログラムは事前コンパ イルされて仮想マシン用のバイトコードに変換される.次に仮想マシンをシミュ レートしてバイトコードを逐次的に実行する.チャンクの行った大域環境に対 する変更は,そのチャンクの実行が終わったあとも保たれる.

チャンクを事前コンパイルしたものをバイナリ形式でファイルに保存すること もできる.詳細は luac プログラムを参照せよ.Lua は自動的にファイ ル形式を認識するので,バイナリ形式の Lua プログラムはテキスト形式のも のと相互に交換可能である.

3. 型とタグ

Luaは 動的に型付けを行う言語であり,変数は型を持たないで,値が型を 持っている.したがって,変数の型を定義することはない.全ての値は型を持っ ており,さらに タグを持つ.

Luaでは6つの基本的な型として, nil 数値 文字列 関数 ユーザデータ がある.nil 型は nil という値の型で あり, nil は他のどの値とも異なる性質を持つ. 数値は実数(倍精度浮動小数点)である. 文字列は任意の 8 ビットの文字の系列であり,埋め込まれたゼロ (¥0) (embedded zeros) を含んでも良い(4節参照).

関数は変数に保存することができ,他の関数の引数として与えることができ, 結果として返したりすることができるので,いわゆるファーストクラスの値 (first class values) と考えられる.Lua では Lua 言語で書かれた関数だけ でなく C 言語で書かれた関数も呼ぶことができ(操作することもできる),そ れらはタグによって識別されている.すなわち,Lua 言語で書かれた関数はす べて同じタグを持ち,C 言語で書かれた関数のもつタグとは異なっている. tag 関数は指定された値のタグを返す(6節参照).

ユーザデータ型は任意の C 言語内のポインタを Lua の変数として扱う ために使われる.これは C 言語におけるvoid * に対応し,代入と等価性の判 定の他には Lua での演算は定義されていない.しかし, タグ関数を使う ことによってプログラマはユーザデータの値に対する演算を定義することがで きる(4.7節参照).

テーブル型は連想配列を実現したもので,数値だけでなく nil を 除く他の任意の値でインデクスできる配列である. したがって通常の配列の他に,シンボル表,集合,レコード,グラフ,木構造 等を表現できる.テーブルは Lua における主要なデータ構造である.

レコードを表現するには,フィールドの名前をインデクスとして使う.Luaで は, a.name という表現は a["name"] と等価である.また,Lua では関数がファーストクラスの値なので,関数をテーブルの要素にすることも できる.また t:f(x) という表現は t.f(t,x) と等価であり,こ れはテーブル t 中の f をテーブルそれ自体を最初の引数にして 呼ぶことである(4.5.8節参照).

テーブルは Lua 中の オブジェクトであり,値ではないことに注意された い.変数はテーブルへの 参照を値として持つことはできるが,テーブル それ自体を持つことはできない. 値を代入したり,関数にパラメータとして渡したり,返り値として渡したりす るのは,常にテーブルへの参照が対象であり,その時にテーブルの複製が発 生することはない.またテーブルは必ず明示的に作成して使用する (4.5.6節参照).

nil型, 数値型, 文字列型はそれぞれ別のタグを持っており, 各型の値は事前に定義された同一のタグを持っている.前述の通り 関数 型の値には 2 種類のタグがあり,Lua の関数なのか C言語の関数なのかによっ て異なる. ユーザデータ型と テーブル型の変数は,プログラマが 任意のタグを割り当てることもできる(4.7節参照). tag 関数は指 定された値のタグを返す.タグは newtag 関数によって作成され, settag 関数によってテーブルのタグを変更できる(6節参照).ユー ザデータ型の値のタグは,C言語側からのみ設定することができる(5.6節 参照).タグは,主にあるイベントが発生したときにどうするかを選択するた めに使われるが,それは タグ関数とよばれ,Lua 言語の機能を拡張する ための仕組みである(4.7節参照).

4. Lua 言語

この節では Lua の字句,構文,機能について説明する.

4.1 字句使用の慣習

Lua の 識別子は他の言語と同様に,アルファベットと数字と下線の任意 の系列であり1文字目が数字でないものとする.他の言語と異なる点は,アル ファベットの定義が設定されているロカール (locale) に従うことである.現 在のロカールでアルファベットと見なされる文字は識別子に使うことができる. 以下の語は 予約語であり,識別子として使うことはできない.


       and       break     do        else      elseif
       end       for       function  if        in
       local     nil       not       or        repeat
       return    then      until     while

Lua は大文字と小文字を区別する. and は予約語であるが, And and (ロカールに依存する)の2つは区別され,識別子として使う ことができる.Lua の慣習として,下線で始まる大文字の識別子( _INPUT など)は内部変数用に予約されている. 他の語としては次のものがある.


       ‾=    <=    >=    <     >     ==    =     +     -     *     /     
       (     )     {     }     [     ]     ;     ,     .     ..    ...

文字列は 2 つの対応する ' " で囲まれることもあり, 以下に示す C 言語のような特殊文字を含んでも良い.


       ¥a  ベル
       ¥b  一文字後退
       ¥f  フォームフィード
       ¥n  改行
       ¥r  復帰
       ¥t  水平タブ
       ¥v  垂直タブ
       ¥¥  バックスラッシュ
       ¥"  2重引用符
       ¥'  1重引用符
       ¥改行  (これはバックスラッシュの後で実際に改行したもの.文字列に改行が入る)

` ddd' を 3 桁以下の 10 進数として,`¥ddd' のようなエスケー プシーケンスで文字を表しても良い. Lua の文字列はどのような 8 ビットの値を含んでいても良い. 埋め込まれたゼロを指定するときは とする.

文字列は対応する [[..]] で囲んだ文字で与えることもできる. この形式は何行かに渡ってもよく, エスケープシーケンスが含まれていても 解釈されない.この形式は,プログラムの一部や引用記号を含む文字列を定義 するのに便利である. 例えば,アスキー文字コードが用いられている場合には,以下の3つは等価な 文字列リテラルである.


        1) "alo¥n123¥""
        2) '¥97lo¥10¥04923"'
        3) [[alo
           123"]]

コメント - の出現後改行までであるが,文字列中に含まれる 場合を除く.また,チャンクの最初の行が # で始まる場合にはコメン トとして解釈される.これは Lua を Unix システム上でスクリプトのインタ プリタとして用いる際に有効な機能である(7.4節参照).

数値定数は,小数部や指数部があっても良い.数値定数の例を以下に示す.


       3     3.0     3.1416  314.16e-2   0.31416E1

4.2 自動的な型変換

Lua では実行時の型変換が自動的に行われることがある.算術演算が文字列に 対して行われた時は,適当な規則に従って文字を数値に変換を試みる.逆に, 文字列があるべきところに数値がある場合には,数値は適当な形式で文字列に 変換される.用いられる変換の形式は,数値から文字列へ変換した後に文字列 から数値へ変換した場合に, 完全に一致するように選択される.そのた め,数値を文字列に変換した場合に,見やすい表現にならないこともある.数 値から文字列への変換形式を厳密に指定するには, format 関数を用いる (6.1節参照).

4.3 調整

Lua の関数は一般に複数の値を返す.型宣言が無いため,(システムは)関数が 呼ばれたときには,関数の引数の数や返り値の数は不明である.したがって値 のリストの長さは,必要に応じて実行時に 調整 される.値のリストが 必要より長い場合は,残りの値は捨てられる.短い場合は,必要なだけ nil が加えられる.この調整は多重代入(multiple assignments) (4.4.1節参照)や関数呼び出し(4.5.7節参照)で生じる.

Lua では関数は複数の値を返すことができる.型宣言が無いために,ある関数 の呼び出しで必要な引数の数や返り値の数を,システムは知ることができない. そのため,値のリストは実行時に 調整されて必要な長さにされることが ある.必要以上の個数の値がある場合には,余分な値は捨てられる.必要な数 だけ値が無い場合には,必要なだけ nil で埋められる. 調整は複数値の代入(4.4.1節参照)や関数呼び出し(4.5.7節参照)で行われる.

4.4 文

Lua では Pascal や C と同様に,代入,制御構造,関数呼び出しといった文 が用いられる.その他,テーブルの生成(4.5.6節参照)や,局所変数の宣 言(4.4.5節参照)といった文も用いられる.

4.4.1 ブロック

ブロックは文の系列である.構文的には,ブロックはチャンクと等価である.


       block ::= chunk

ブロックの境界を明示することもできる.


       stat ::= do block end

明示されたブロックは局所変数の有効領域を規定するのに用いることができる. (4.4.5節参照).また, return 文や break 文を他のブロッ クの途中に入れるためにも利用できる.

4.4.2 代入

Lua では多重代入が可能である.構文的には代入の左辺が変数の系列で,右辺 が式の系列である.各辺の要素はコンマで区切る.


       stat ::= varlist1 `=' explist1
       varlist1 ::= var {`,' var}

代入文では右辺の値と左辺の添字がすべて評価された後に,代入が行われる. 以下の例では,


       i = 3
       i, a[i] = 4, 20

a[3] に 20 が代入され, a[4] には影響を与えない. a[i] i は 4 が代入される前に評価されるからである.

多重代入は2つの値を入れ替えるのに用いることができる.


       x, y = y, x

多重代入の(右辺と左辺の)系列は長さが異っても良い.代入の前に,値の系 列は変数の系列の長さに合わせて調整される(4.2節参照).

名前の単独の出現は大域変数,局所変数,引数を表す.


       var ::= name

角括弧は表のインデクスを表す.


       var ::= varorfunc `[' exp1 `]'
       varorfunc ::= var | functioncall

varorfunc はテーブル型の値であり, exp1 で示されるフィール ドの値が得られる.

var.NAME の形式は, var["NAME"] と等価である.


       var ::= varorfunc `.' name

大域変数やインデクスづけされた変数に対して代入や評価を行う時の効果は, タグ関数によって変化させることができる(4.7節参照).実際, xを 大域変数としたとき, x = val setglobal("x",val) は等価で あり, t[i] = val settable_event(t,i,val) は等価である. 詳細は 4.7節 を参照せよ( setglobal 関数は基本ライブラリで定義 されている. settable_event 関数は説明の都合上用いた).

4.4.3 制御構造

if while repeat は通常の意味を持ち,類似の形式で用 いられる.


       stat ::= while exp1 do block end
       stat ::= repeat block until exp1
       stat ::= if exp1 then block {elseif exp1 then block} [else block] end

制御構造中の条件式 exp1 は何らかの値を返す. nil 以外の全て の値は真と解釈され, nil だけが偽と解釈される.

return 文は関数やチャンクから値を返すのに用いられる.関数やチャ ンクは複数の値を返すことも可能なため,return 文の形式は以下のようにな る.


       stat ::= return [explist1]

break 文はループの実行を終了し,ループの次の文に制御を移す.


       stat ::= break

break は最も内側のループ( while repeat for)を 終了する.

注意: 構文的な理由から, return break は,ブロック の最後の文でなければならない. return break をループの途 中に書く必要がある場合には,` do return end' のように明示的に内部 ブロックを用いる必要がある.このようにすれば, return はブロック の最後の文になる.

4.4.4 for文

for 文には,数値用とテーブル用に応じて2種類の形式がある.

数値用の for 文は次のような形式である.


       stat ::= for name `=' exp1 `,' exp1 [`,' exp1] do block end

以下の 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

ここで,以下の点に注意せよ.

テーブル用の for 文は,与えられたテーブル中の全ての (index,value) に対して繰り返しを行う.形式は以下のようになる.


       stat ::= for name `,' name in exp1 do block end

以下の for 文は,


       for index, value in exp do block end

次の記述と等価である.


       do
         local _t = exp
         local index, value = next(t, nil)
         while index do
           block
           index, value = next(t, index)
         end
       end

ここで,以下の点に注意せよ.

4.4.5 返り値を使わない関数呼び出し

関数呼び出しは副効果があるため,関数呼び出しは返り値を用いずに文として 実行できる.


       stat ::= functioncall

この場合には,返り値は捨てられる.関数呼び出しは 4.5.7節 で説明する.

4.4.6 局所変数の定義

局所変数はブロック内の任意の場所で宣言できる.宣言には初期値を与えても 良い.


       stat ::= local declist [init]
       declist ::= name {`,' name}
       init ::= `=' explist1

初期値の代入は多重代入と同様の機能を持つ.初期値がない場合には,変数 は nil で初期化される.

チャンクもブロックであるので,明示的にブロックを用いなくても局所変数を 定義できる.局所変数の有効範囲は宣言のからブロックの最後までで ある.よって local print=print という記述は print という名 前の局所変数を宣言し,同名の 大域変数の値を初期値とすることになる.

4.5 式

4.5.1 基本的な式

Lua での基本的な式には,以下のようなものがある.


       exp ::= `(' exp `)'
       exp ::= nil
       exp ::= number
       exp ::= literal
       exp ::= var
       exp ::= upvalue
       exp ::= function
       exp ::= functioncall
       exp ::= tableconstructor

数値(数値定数)と文字列リテラルは 4節, 変数は 4.4.1節, 上位値(upvalue)は4.5.9節, 関数の定義( 関数)は 4.5.8節, 関数呼び出しは 4.5.7節, テーブルの生成関数は 4.5.6節 で説明する.

大域変数 x の参照は getglobal("x") と等価である.添字を伴う 変数の参照 t[i] は gettable_event(t,i) と等価である.これらの関 数の記述は 4.7節 を参照せよ.(関数 getglobal は基本ライブラ リ中で定義されている.関数 gettable_event は説明のために用いた).

非終端記号 exp1 は,式によって返される値(一般には値のリスト)が1 つの値に調整されることを示す.


       exp1 ::= exp

4.5.2 算術演算子

Lua の算術演算子には次のものがある.


       +  加算
       -  減算
       *  積算
       /  除算
       ^  べき乗
       単項の -

演算の対象が数値,または数値に変換可能な文字列(4.1節参照)の場合 には,べき乗以外は通常の演算が行われる.他の場合は,適切なタグ関数が呼 ばれる(4.7節参照).べき乗の場合は常にタグ関数が呼ばれる. 標準数学ライブラリは数値に対するタグ関数を再定義しており,べき乗も通常 の演算が行われる.

4.5.3 関係演算子

Lua の関係演算子には次のものがある.


       ==    ‾=    <     >     <=    >=

これらの演算子は,結果が偽の場合 nil を返し,真の場合 nil でない値を返す.

等値演算子 ( ==) は,はじめに引数のタグを比較する.両者が異なる場 合には nil を返し,等しい場合には値が比較される.数値や文字列は 通常の方法で比較される.テーブル,ユーザデータ,関数は参照が比較され, 同一の対象である場合のみ等しいとされる.  = 演算子は 等値演算子 ( ==) の否定である.

注意 4.1節の変換規則は,等値演算子による比較の時には ul適用されない. したがって,"0"==0 はとなり, t[0] t["0"] はテー ブルの他の要素を表す.

演算子の作用する順序は以下のようになる.両方の引数が数値の場合,数値と して比較される.次に両方の引数が文字列の場合,辞書順で比較される.他の 場合には,"lt" タグメソッドが呼ばれる(4.7節参照).

4.5.4 論理演算子

Luaの論理演算子は以下の3つである.


       and   or    not

制御構造と同様に,論理演算子は nil を偽,他の値を真とと解釈する.

連言演算子 and は,1つ目の引数が nil の時 nil を返 す.そうでなければ2つ目の引数を返す.選言演算子 or は,1つ目の 引数が nil と異なれば1つ目の引数を返す.そうでなければ2つ目の 引数を返す. and orは短絡評価を行うため,2つ目の引数は必 要な時にのみ評価される.

Lua には論理演算子を使った便利な慣用表現がいくつかある.


       x = x or v

これは次と等価である.


       if x == nil then x = v end

x が定義されていない場合は v が代入される.また,


       x = a and b or c

は, x = (a and b) or c と解釈され,これは,


       if a then x = b else x = c end

と等しい.ただし b nil であってはならない.

4.5.5 連結演算子

文字列を連結する演算子は2つのピリオド(` ..')で表される. 両方の引数が文字列または数値の場合には,4.1節の規則に従い文字列に 変換される.他の場合には,``concat'' タグメソッドが呼ばれる(4.7節 参照).

4.5.6 演算子の優先順位

Lua の演算子の優先順位を,順位の低い順に示す.


       and   or
       <     >     <=    >=    ‾=    ==
       ..
       +     -
       *     /
       not   - (unary)
       ^

二項演算子は左から右の順で結合されるが,^ (べき乗)は右から左の 順である.

注意: 事前コンパイラは最適化のため,通常の演算結果に影響を与えない場合 には,結合則を満たす演算子 ( .. + 等) の評価順序を入れ替 えることがある.しかし,これらの演算子に結合則を満たさないタグ関数を設 定した場合には,最適化によって演算結果が変化することがある.

4.5.7 テーブル生成子

テーブル生成子はテーブルを作成する式であり,評価されるたびに新しいテー ブルを生成する.生成子で空のテーブルを生成したり,テーブル内の要素の初 期値を与えてテーブルを生成したりすることができる.テーブル生成子の一般 的な構文は以下のようになる.


       tableconstructor ::= `{' fieldlist `}'
       fieldlist ::= lfieldlist | ffieldlist | lfieldlist `;' ffieldlist | ffieldlist `;' lfieldlist
       lfieldlist ::= [lfieldlist1]
       ffieldlist ::= [ffieldlist1]

lfieldlist1 はリストを初期化するのに用いられる.


       lfieldlist1 ::= exp {`,' exp} [`,']

リスト中の要素には1から始まり連続する数値のインデクスが与えられる. 例えば,


       a = {"v1", "v2", 34}

は,以下と等価である.


       do
         local temp = {}
         temp[1] = "v1"
         temp[2] = "v2"
         temp[3] = 34
         a = temp
       end

ffieldlist1 はテーブルの他の要素を初期化するのに用いる.


       ffieldlist1 ::= ffield {`,' ffield} [`,']
       ffield ::= `[' exp `]' `=' exp | name `=' exp

例えば,


       a = {[f(k)] = g(y), x = 1, y = 3, [0] = b+c}

は,以下と等価である.


       do
         local temp = {}
         temp[f(k)] = g(y)
         temp.x = 1    -- or temp["x"] = 1
         temp.y = 3    -- or temp["y"] = 3
         temp[0] = b+c
         a = temp
       end

{x = 1, y = 4} という式は, {["x"] = 1, ["y"] = 4} と等価である.

どちらの初期化の記法も,最後の要素の後にコンマをつけて良い.また,セミ コロンで区切ることで,両方の記法を同一の生成子内で用いることができる.


       x = {;}
       x = {"a", "b",}
       x = {type="list"; "a", "b"}
       x = {f(0), f(1), f(2),; n=3,}

4.5.8 関数呼び出し

Luaの関数呼び出しは,次の形式で行う.


       functioncall ::= varorfunc args

はじめに, varorfunc が評価され, 関数型の場合は指定された引 数で関数が呼ばれる.他の場合には varorfunc の値を1番目の引数, 2番目以降を指定された引数として,"function" タグ関数が呼ばれる.

以下の形式は,関数を呼ぶのに用いられる.


       functioncall ::= varorfunc `:' args

v:name(...) という記法は, v.name(v, ...) と等価である.た だし v は一度しか評価されない.

引数は次のような形式である.


       args ::= `(' [explist1] `)'
       args ::= tableconstructor
       args ::= literal
       explist1 ::= {exp1 `,'} exp

すべての引数は呼び出し前に評価される. k引数リストが新しく生成されるテーブルのみの場合, f{...} f({...}) と等価である. また引数が単一の文字列リテラルの場合, f `...' f(`...') と等価である. f "..." f[[...]]についても同様である.

関数は複数の値を返す場合があるため(4.4.2節参照),返り値の数は利用 する前に調整される(4.2節参照).関数が返り値を用いない形式で呼ばれ た場合(4.4.4節),返り値のリストは長さ 0 に調整され,全ての返り値は 捨てられる.返り値が1つ必要な環境で関数が呼ばれた場合には(文法的には 非終端記号 exp1 と表される),返り値のリストは長さ 1 に調整され, はじめの要素以外は捨てられる.返り値が複数許容される環境で呼ばれた場合 には,(文法的には非終端記号 exp と表される) 調整は行われない. 複数の返り値が許容される環境は,代入文の左辺の最後の要素,引数リスト, return 文だけである.以下に例を示す.


       f()                -- 返り値は捨てられる
       g(f(), x)          -- f() の返り値は1個に調整される
       g(x, f())          -- g は x と f() の全ての返り値を受け取る
       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() の返り値全てを返す

4.5.9 関数の定義

関数の定義の構文を以下に示す.


       function ::= function `(' [parlist1] `)' block end
       stat ::= function funcname `(' [parlist1] `)' block end
       funcname ::= name | name `.' name | name `:' name

以下の形式は,


       function f () ... end

以下と等価である.


       f = function () ... end

また,以下の形式は,


       function v.f () ... end

以下と等価である.


       v.f = function () ... end

関数の定義は実行可能な式であり, 関数型の値を返す.Lua の事前コン パイラがチャンクを処理する際に,関数の本体も事前コンパイルされる.Lua が関数の定義を行う時には,常に上位値 (upvalue) が固定され(4.5.9節 参照),関数が 実体化される(または 閉じられる).この関数の実体 (または 閉包)が式の最終的な値である.同じ関数の異なる実体は,異な る上位値を持つことがある.

関数の仮引数は局所変数として扱われ,実引数で初期化される.


       parlist1 ::= `...'
       parlist1 ::= name {`,' name} [`,' `...']

関数が呼ばれると,引数のリストは仮引数のリストの長さに合わせて調整 される(4.2節参照).ただし,関数の仮引数のリストの最後に (`...') がある場合は, 可変の引数リストを持つ関数 (vararg function) となる. 可変の引数リストを持つ関数では調整は行われず,余分な引数は 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 文を用いて返される(4.4.2節参照). 関数の最後に来ても return 文が無い場合には,関数は値を返さない.

以下の形式は,


       funcname ::= name `:' name

self という暗黙の追加の引数を持つ関数を定義する. したがって,以下の形式は,


       function v:f (...) ... end

次と等価である.


       v.f = function (self, ...) ... end

関数は self という名前の追加の引数を受け取る.

4.6 可視性と上位値

関数の内部では,仮引数を含む局所変数および大域変数を参照できる. ただし,大域変数が上位の関数 2の中で同名の局所変数によって 隠されている場合には参照することができない.関数が呼ばれたときに は上位の関数の局所変数は存在しないため,それらの変数を参照することもで きない. しかし,上位の関数の局所変数のを参照することはできる.これは 上位値 (upvalue)と呼ばれる形式で行われる.上位値の形式は,


       upvalue ::= `%' name

となる.上位値は変数と似ているが,上位値の出現する関数が実体化された時に 上位値の値は 固定される.上位値の名前は,現在の関数が定義されてい る位置で参照できる変数の名前,すなわち大域変数または1つ上位の関数の局 所変数の名前でなければならない. 上位値がテーブルの場合には,テーブル自体への参照(参照が上位値の値とな る)のみが固定され,テーブルの中身は変更することができる.テーブルを上 位値として用いることで,関数に局所的だが書き換えの出来る状態を持たせる ことができる.


       a,b,c = 1,2,3   -- 大域変数
       local d
       function f (x)
         local b = {}  -- x, b は f の局所変数であり,b は 大域変数 b を隠す.
         local g = function (a)
           local y     -- a, y は f の局所変数
           p = a       -- OK, 局所変数 a 
           p = c       -- OK, 大域変数 a 
           p = b       -- エラー,有効範囲 (scope) の外
           p = %b      -- OK, 固定された変数 b (f の局所変数) 
           %b = 3      -- ERROR: 上位値は変更できない
           %b.x = 3    -- OK, テーブルの中身を変更
           p = %c      -- OK, 固定された大域変数 c
           p = %y      -- ERROR: g が定義されている環境から y は見えない
           p = %d      -- ERROR: g が定義されている環境から d は見えない
         end           -- g
       end             -- f

4.7 エラー処理

Lua は拡張言語なので,Lua のすべての実行はC 言語で記述された Lua を組 み込んでいる プログラム が Lua のライブラリを実行することにより行われ る.Lua のプログラムのコンパイル中または実行中にエラーが起こった場合に は, _ERRORMESSAGE nil でない場合は _ERRORMESSAGE 関数が呼ばれ,対応する Lua ライブラリの関数 ( lua_dofile lua_dostring lua_dobuffer lua_callfunction)が終了し,エラーの状況を返す.

メモリの割り付けの失敗によるエラーはこの規則には従わない.メモリの割り 付けが失敗した時には _ERRORMESSAGE 関数を実行することができない 場合がある.その時は対応する Lua ライブラリの関数はただちに終了し, LUA_ERRMEM という特別の値を返す.これらのエラー値は lua.h で定義されている(5.7節参照).

_ERRORMESSAGE 関数はエラーの説明となる文字列を引数とする. _ERRORMESSAGE は通常 _ALERT 関数を実行し,エラーメッ セージが標準エラー出力に出力される(6節参照).標準入出力ライブ ラリはスタックの履歴等の情報を表示するため, _ERRORMESSAGE を再 定義しデバッグ機能(6.5節参照)を利用している.

プログラム中で error 関数を呼ぶことで,エラーを明示的に生成する ことができる(6節参照).また, call 関数を用いることで, エラーを 補足する (catch)ことができる(6節参照).

4.8 タグ関数

Lua は言語機能を拡張する タグ関数という強力な方法を提供している. タグ関数はプログラマが定義できる関数であり,プログラムの実行中のある特 定の時点で実行され,Lua の通常の振舞いを変更することができる.この特定 の時点は イベントと呼ばれる.

イベントが生じたときに実行されるタグ関数は,イベントに関わる値のタグに 基づいて決められる. settagmethod 関数を使うと, ( タグ, イベント)対に関連づけられたタグ関数を変更することがで きる. settagmethod 関数の1つ目の引数はタグ,2番目の引数はイベン トの名前(文字列.以下を参照),3番目の引数は登録する関数である.関数と して nil を指定した場合には,指定された(タグ,イベント)の振舞い は初期状態に戻る. settagmethod 関数は,以前に登録されていた関数 を返す. gettagmethod 関数は,タグとイベント名を引数とし,現在登 録されている関数を返す.

タグ関数は以下に挙げる名前を持つイベントにおいて実行される.タグ関数の 機能は,各イベントでのインタプリタの振舞いを表す関数で記述した. この関数はタグ関数が実行される時点に加え,引数,結果,初期状態での 振舞いを示す.この関数の記述は 説明のためのものであり,実際はより 効率的に実行される形で,インタプリタに組み込まれている.以下で使われる rawget, tonumber, call等の関数は,6節を参照せよ.


``add''
: + 演算子が数値でない引数に適用されたとき呼ばれる.

以下に示す getbinmethod 関数は,Lua が2項演算に対してタグ関数を 選ぶ手順を定義している.まず1つ目の引数に対して,適切なタグ関数を探す. 見つからない場合には,2つ目の引数に対して同様に試みる.両方に失敗した 場合には,タグ 0 からタグ関数を得る.


           function getbinmethod (op1, op2, event)
             return gettagmethod(tag(op1), event) or
                    gettagmethod(tag(op2), event) or
                    gettagmethod(0, event)
           end

この関数を用いることで,``add'' イベントに対するタグ関数は,以下のようになる.


           function add_event (op1, op2)
             local o1, o2 = tonumber(op1), tonumber(op2)
             if o1 and o2 then  -- 両方の引数は数値
               return o1+o2  -- ここでの `+' は基本の `add'
             else  -- 少なくとも1つの引数は数値ではない
               local tm = getbinmethod(op1, op2, "add")
               if tm then
                 -- 2つの引数とイベント名を追加の引数として関数を呼ぶ
                 return tm(op1, op2, "add")
               else  -- 利用可能なタグ関数がない: 初期設定時の処理
                 error("unexpected type at arithmetic operation")
               end
             end
           end


``sub''
: - 演算子が数値でない引数に適用されたとき呼ばれる. 処理は``add'' イベントと同様である.


``mul''
: * 演算子が数値でない引数に適用されたとき呼ばれる. 処理は``add'' イベントと同様である.


``div''
: / 演算子が数値でない引数に適用されたとき呼ばれる. 処理は``add'' イベントと同様である.


``pow''
: ^ 演算子(べき乗)が適用されたとき呼ばれる.引数が数値であっても 同様に呼ばれる.


           function pow_event (op1, op2)
             local tm = getbinmethod(op1, op2, "pow")
             if tm then
               -- 2つの引数とイベント名を追加の引数として関数を呼ぶ
               return tm(op1, op2, "pow")
             else  -- 利用可能なタグ関数がない: 初期設定時の処理
               error("unexpected type at arithmetic operation")
             end
           end


``unm''
: 単項演算子の - が数値でない引数に対して適用されたときに呼ばれる.


           function unm_event (op)
             local o = tonumber(op)
             if o then  -- 数値引数
               return -o  -- ここでの `-' 基本の `unm'
             else  -- 引数は数値でない
               -- 引数のタグ関数の取得を試みる
               -- 無ければ,"大域的な" タグ関数取得を試みる (タグ 0)
               local tm = gettagmethod(tag(op), "unm") or
                          gettagmethod(0, "unm")
               if tm then
                 --引数,nil とイベント名を追加の引数として関数を呼ぶ
                 return tm(op, nil, "unm")
               else  -- 利用可能なタグ関数がない: 初期設定時の処理
                 error("unexpected type at arithmetic operation")
               end
             end
           end


``lt''
: 順序演算子が数値でない対象に対して適用されたとき呼ばれる. < 演算子に対応する.


           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 tm = getbinmethod(op1, op2, "lt")
               if tm then
                 return tm(op1, op2, "lt")
               else
                 error("unexpected type at comparison");
               end
             end
           end

他の順序演算子は,通常の等値変換にしたがってこのタグ関数を用いる.


           a>b    <=>  b<a
           a<=b   <=>  not (b<a)
           a>=b   <=>  not (a<b)


``concat''
: 連結演算子か文字列以外の対象に適用されたとき呼ばれる.


           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 tm = getbinmethod(op1, op2, "concat")
               if tm then
                 return tm(op1, op2, "concat")
               else
                 error("unexpected type for concatenation")
               end
             end
           end


``index''
: テーブル中に無いインデクスに対する値を探す時に呼ばれる. ``gettable'' イベントを参照せよ.


``getglobal''
: 大域変数の値が参照されるときに呼ばれる.このタグ関数は nil およ び newtag 関数によって新たに作られるタグに対してのみ設定できる. タグは大域変数の 現在の値のものである.


           function getglobal (varname)
             -- 大域変数のテーブルを参照
             local value = rawget(globals(), varname)
             local tm = gettagmethod(tag(value), "getglobal")
             if not tm then
               return value
             else
               return tm(varname, value)
             end
           end

getglobal 関数は,標準ライブラリ関数中で定義されている(6節 参照).


``setglobal''
: 大域変数へ値を代入するときに呼ばれる.このタグ関数は数値,文字列,テー ブル,初期設定時のタグを持つユーザデータには設定することができない.


           function setglobal (varname, newvalue)
             local oldvalue = rawget(globals(), varname)
             local tm = gettagmethod(tag(oldvalue), "setglobal")
             if not tm then
               rawset(globals(), varname, newvalue)
             else
               tm(varname, oldvalue, newvalue)
             end
           end

setglobal 関数は,標準ライブラリ関数中で定義されている(6節 参照).


``gettable''
: インデクスを持つ変数を参照するときに呼ばれる.このタグ関数は, 初期設定時のタグを持つテーブルに対しては設定できない.


           function gettable_event (table, index)
             local tm = gettagmethod(tag(table), "gettable")
             if tm then
               return tm(table, index)
             elseif type(table) ‾= "table" then
               error("indexed expression not a table");
             else
               local v = rawget(table, index)
               tm = gettagmethod(tag(table), "index")
               if v == nil and tm then
                 return tm(table, index)
               else
                 return v
               end
             end
           end


``settable''
: インデクスを持つ変数に値を代入するときに呼ばれる.このタグ関数は, 初期値のタグを持つテーブルに対しては設定できない.


           function settable_event (table, index, value)
             local tm = gettagmethod(tag(table), "settable")
             if tm then
               tm(table, index, value)
             elseif type(table) ‾= "table" then
               error("indexed expression not a table")
             else
               rawset(table, index, value)
             end
           end


``function''
: 関数でない対象に対して関数呼び出しを行ったときに呼ばれる.


           function function_event (func, ...)
             if type(func) == "function" then
               return call(func, arg)
             else
               local tm = gettagmethod(tag(func), "function")
               if tm then
                 for i=arg.n,1,-1 do
                   arg[i+1] = arg[i]
                 end
                 arg.n = arg.n+1
                 arg[1] = func
                 return call(tm, arg)
               else
                 error("call expression not a function")
               end
             end
           end


``gc''
: Luaがユーザデータのガーベジコレクションをするときに呼ばれる.このタグ 関数は C 言語からのみ設定でき,初期設定時のタグを持つテーブルに対して は設定できない.ガーベジコレクションの対象となるユーザデータ毎に,以下 の関数と等価な処理が行われる.


           function gc_event (obj)
             local tm = gettagmethod(tag(obj), "gc")
             if tm then
               tm(obj)
             end
           end

ガーベジコレクション時には,ユーザデータのタグ関数はタグが作られた順番 と逆順に呼ばれる.すなわち,はじめに呼ばれるのはプログラムで最後に作ら れたタグである.さらに,ガーベジコレクションの処理の最後に,Luaは gc_event(nil) の呼び出しと等価な処理を行う.

5. プログラムインターフェイス

この章では Lua の API について説明する.API は,Lua を組み込むプログラ ムが Lua を操作するのに用いる C 言語の関数の集合である.API の関数,関 連する型や定数の定義は,ヘッダファイル lua.h に記述されている.

注意: 「関数」という語を用いた場合でも,実装は マクロで行われてい る場合がある.これらのマクロ中では引数は必ず一度のみ評価され,隠れた副 作用が起こることはない.

5.1 状態

Luaのライブラリは完全に再入可能 (reentrant) であり,大域変数を持たない. Lua のインタプリタの状態 (大域変数,スタック,タグ関数等) は動的に割り 当てられた lua_State 型の領域中に保持される.全てのライブラリ関 数の1つめのの引数として,状態を渡す必要がある( lua_openを除 く.以下参照).

API 関数を呼ぶ前に,Lua インタプリタの状態を生成するため,以下を実行する.


       lua_State *lua_open (int stacksize);

lua_open の唯一の引数は,インタプリタのスタックの大きさである. (関数呼び出しは引数ごとにスタック上の領域を1使用する.局所変数や一時 的な値は,管理のため領域を2使用する.スタックは20の余分の領域を持って いる必要がある.再帰呼び出し無しの小規模の実装であれば,スタックのサイ ズは100で十分である). stacksize が 0 の場合には,初期設定時の大 きさ(1024)が用いられる.

lua_open で生成された状態を解放するには,以下を実行する.


       void lua_close (lua_State *L);

この関数は,指定された Lua 環境中の全てのオブジェクトを破棄し(対応する ガーベジコレクションタグ関数を呼ぶ),状態によって動的に割り当てられて いた領域を解放する.プログラムが終了したときにはすべての資源は解放され るので,通常はこの関数を呼ぶ必要はない.デーモンやウェブサーバ等長い間 動き続けるプログラムでは肥大化を防ぐため,必要のなくなった状態は解放す る必要があるだろう.

lua_openを除き,全てのライブラリ関数は状態を1つめの引数として 渡す必要がある.

5.2 スタックとインデクス

Lua は C 言語との間で値を受け渡す際に スタックを用いる.スタック中 の各要素は Lua の値 (nil, 数値,文字列など)を表す.

簡単のため,ほとんどの問い合わせ操作は厳密なスタック操作の方法には従っ ていない.スタック中の全ての要素を インデクスで参照できる. 正のインデクスはスタック中の 絶対位置を表す (インデクスは 1 から始まり,Cのように0からではない). 負のインデクスはスタックの一番上からの 差分を表す. 詳しく言うと,スタック中の要素の数を n とすると, インデクス 1 は最初の要素 (はじめにスタックに入れられた要素) を表し,インデクス n は最後の要素を表す. -1 もまた最後の要素を表し(これはスタックの一番上の要素である), インデクス -n は最初の要素を表す. インデクスが 1 以上でスタックの要素数以下であるとき ( 1 <= abs(インデクス) <= top), インデクスは 有効であるという.

スタックの一番上の要素のインデクスは,次の関数を実行することで得られる.


       int lua_gettop (lua_State *L);

インデクスは 1 から始まるので, lua_gettop の返り値はスタック中の 要素数と同じになる(スタックが空の時 0 となる).

Lua の API を扱う際は, スタックのあふれを自分で管理する必要があ る.次の関数は,スタックの空き容量を返す.


       int lua_stackspace (lua_State *L);

Lua が C 言語を呼ぶ際には,少なくとも LUA_MINSTACK の空き容量が ある必要がある. LUA_MINSTACK lua.h 中で定義されており, 少なくとも 16 である.プログラムがスタックに要素を繰り返し入れる際には, スタックの残り容量を考える必要がある.

ほとんどの問い合わせ関数は,インデクスの値がスタックの最大の大きさ以下 の値であれば受理する.このインデクスは 受理可能なインデクスと呼 ばれる.受理可能なインデクスは以下のように定義される.


(インデクス < 0 && abs(インデクス) <= スタック中の要素数) ||
(インデクス > 0 && インデクス <=  スタック中の要素数 + スタックの空き容量)

0 は 受理可能なインデクスではないことに注意せよ.

5.3 スタックの操作

スタック操作に関する 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);

lua_settop は受理可能なインデクスまたは 0 を受け取り,スタック の一番上を指定されたインデクスに設定する.指定されたインデクスが現在の スタックの一番上よりも大きい場合には,追加される要素は nil で初 期化される. index として 0 が指定されると,スタック中の要素はす べて捨てられる.API では以下の有用なマクロが定義されている.


       #define lua_pop(L,n) lua_settop(L, -(n)-1)

これは先頭の n 個の要素をスタックから取り除く.

lua_pushvalue はインデクスで指定された要素の複製をスタックの先 頭に入れる. 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  (変化無し)
       lua_settop(L, -3)      --> 30 10 20
       lua_settop(L, 6)       --> 30 10 20 nil nil nil

5.4 スタック への 問い合わせ

次の関数を用いて,スタック中の要素の型を調べることができる.


       int         lua_type        (lua_State *L, int index);
       int         lua_tag         (lua_State *L, int index);
       int         lua_isnil       (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);

これらの関数に対しては受理可能なインデクスを指定する. lua_type は指定された要素の型に応じて, LUA_TNIL, LUA_TNUMBER LUA_TSTRING LUA_TTABLE LUA_TFUNCTION LUA_TUSERDATA のいずれかの定数を返す. 指定されたインデクスが有効で無い場合には(指定されたスタック上 の位置が空の場合), lua_type LUA_TNONE を返す. これらの定数は次の関数を用いて,文字列に変換できる.


       const char *lua_typename (lua_State *L, int t);

t lua_type の返り値である. lua_typename で 返される文字列は "nil" "number" "string" "table" "function" "userdata" "no value" のいずれかである.

lua_tag はスタック中の要素のタグを返す.有効でないインデクスに対 しては, LUA_NOTAG を返す. lua_is* 関数は,要素が指定された型と互換性のある場合は 1 を返し, そうでなければ 0 を返す.有効でないインデクスに対しては 0 を返す. lua_isnumber 関数は要素が数値または数を表す文字列の場合, lua_isstring 関数は要素が文字列または数値の場合(4.1節参照), lua_isfunction 関数は要素が Lua または C 言語の関数の場合,それ ぞれ 1 を返す. Lua の関数と C 言語の関数を区別するためには, lua_iscfunction を 用いる.数値と数を記述した文字列を区別するためには, lua_type を 用いる.

スタック中の2つの要素を比較するため,次の関数を用いることができる.


       int lua_equal    (lua_State *L, int index1, int index2);
       int lua_lessthan (lua_State *L, int index1, int index2);

これらの関数は Lua での対応する関数と等価である. lua_lessthan4.7節で説明した lt_event と等価であ る.どちらの関数も,指定されたインデクスのどちらかが有効でない場合は 0 を返す.

スタック中の要素の値を特定の C 言語の型に変換したい場合には,以下の関 数を用いることができる.


       double         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_tonumber 関数は指定されたインデクスの要素を浮動小数点に変換 する.要素は数値または数値に変換可能な文字列でなければならない (4.1節参照).そうでない場合, lua_tonumber は 0 を返す.

lua_tostring 関数は Lua の要素を文字列 ( const char*) に変 換する.要素は文字列または数値でなければならず,そうでなければ NULL が返される.この関数は Lua 環境中にある文字列へのポインタを返 す.文字列の最後の文字の後にはゼロ (`¥0') が入れられる(C と同様 である)が,文字列自体がゼロを含む可能性がある.文字列がゼロを含むかど うか確かめるには, lua_strlen を使う必要がある.Lua はガーベジコ レクションの機能を持つため,対応する要素がスタックから除かれた後でも lua_tostring で返された値が有効である保証はない.

lua_tocfunction はスタック中の要素を C の関数に変換する.要素は C の関数でなければならず,そうでなければ NULL が返される. lua_toCFunction 型は,5.12節で説明する.

lua_touserdata 関数は要素を void* 型に変換する.値は ユーザデータ型でなければならず,そうでなければ NULL が返さ れる.

5.5 値をスタックへ入れる

次の関数を用いて,C 言語の値をスタックに入れることができる.


       void lua_pushnumber    (lua_State *L, double n);
       void lua_pushlstring   (lua_State *L, const char *s, size_t len);
       void lua_pushstring    (lua_State *L, const char *s);
       void lua_pushusertag   (lua_State *L, void *u, int tag);
       void lua_pushnil       (lua_State *L);
       void lua_pushcfunction (lua_State *L, lua_CFunction f);

これらの関数は受け取った C 言語の値を,対応する Lua の値に変換してスタッ クに入れる. 特に lua_pushlstring および lua_pushstring は,引数の文字 列の 内部的な複製を生成する. lua_pushstring は C 言語の正しい文字列のみ扱うことができる (正しい文字列とは,ゼロで終わり,埋め込まれたゼロを含まない文字列である). lua_pushlstring はより汎用の関数で,文字列の長さを明示的に指定す ることで,埋め込まれたゼロを含む場合も扱うことができる.

5.6 ガーベジコレクション

Lua ではガーベジコレクションを制御するために2つの値を用いる.1つ目の 値は Lua が使用している動的メモリのバイト数で,2つ目の値はしきい値で ある(Lua が管理しているこのバイト数は完全に正確ではない.これは単なる 下限であり,正確な値との差は通常は 10% 以内である).このバイト数がし きい値を上回ったら,Lua はガーベジコレクションを開始し,「死んだ」オブ ジェクト(Lua から参照できないオブジェクト)のメモリ領域を回収する. 使用メモリのバイト数は修正され,しきい値はこのバイト数の2倍に設定される.

次の関数を用いることで,これらの値を参照できる.


       int  lua_getgccount (lua_State *L);
       int  lua_getgcthreshold (lua_State *L);

返り値の単位はキロバイトである.次の関数を用いて,しきい値を変更するこ とができる.


       void  lua_setgcthreshold (lua_State *L, int newthreshold);

newthreshold の単位もキロバイトである.この関数を呼ぶと,新しい しきい値を設定して,使用メモリのバイト数と比較される.指定したしきい値が このバイト数以下の場合にはガーベジコレクションがすぐに実行される. 実行後に,前述の方法で再びしきい値が設定される.

ガーベジコレクションが使用メモリ量に対して適応的に行われるのを止めたい 場合には,ガーベジコレクションタグ関数を nil に設定し,自分の指 定するしきい値を設定すれば良い(このタグ関数は Lua がしきい値を設定する 際に呼ばれる).

5.7 ユーザデータとタグ

ユーザデータはオブジェクトなので, lua_pushusertag 関数は新しい ユーザデータを作ることがある.

Lua 中に void * 型の指定された値とタグを持つユーザデータがあるな らば,そのユーザデータがスタックに入れられる.そうでなければ,与えられ た値とタグで新しいユーザデータが作られる. tag として LUA_ANYTAG が指定された場合は,タグは無視して,指定された値を持つ ユーザデータを探す.そのようなユーザデータが無い場合には,タグを 0 と して新しいユーザデータが作られる.

ユーザデータは,タグの機能が Lua を組み込んでいるプログラムにしか分か らない別のタグを持つことがある.タグは以下の関数で作られる.


       int lua_newtag (lua_State *L);

lua_settag 関数はスタックの一番上のオブジェクトのタグを変更する (スタックから取り出さない).


       void lua_settag (lua_State *L, int tag);

オブジェクトはユーザデータかテーブルである必要がある.指定された tag lua_newtag を用いて作られる.

5.8 Luaプログラムの実行

Lua を組み込んでいるプログラムは,以下の関数を用いてファイルまたは文字 列の形式の Lua チャンクを実行できる.


       int lua_dofile   (lua_State *L, const char *filename);
       int lua_dostring (lua_State *L, const char *string);
       int lua_dobuffer (lua_State *L, const char *buff,
                         size_t size, const char *name);

これらの関数は成功した場合は 0 を返し,失敗した場合は以下のエラーコー ドの1つを返す( lua.h 中で定義されている).

lua_dofile 関数の引数として NULL が与えられた場合には, 標準入力から入力される内容を実行する. lua_dofile 関数と lua_dobuffer 関数は,事前にコンパイルさ れたチャンクを実行できる.これらの関数は,チャンクがテキスト形式かバイ ナリ形式かを自動的に判別して読み込む( luacプログラム参照). lua_dostring はテキスト形式のソースプログラムのみを実行できる.

lua_dobuffer 関数の3番目の引数には,チャンクの名前を指定する. これはエラーメッセージやデバッグ時の情報として用いられる. NULL が指定された場合には,省略時の名前が用いられる.

これらの関数はチャンクの実行結果の値をスタックに入れる.チャンクは複数 の値を返す可能性がある.そのような場合はスタックの空きにあうように処理 されるが,自分の責任で用いるべきである.これらの関数の実行後にスタック に他の値を入れる場合は, lua_stackspace 関数を用いてスタックの空 きを調べるか,スタックに入れられた返り値が不要な場合は取り除くのが安全 である.例えば,以下のプログラムはファイル中のプログラムを読み込んで実 行し,返り値をすべて取り除き,スタックをプログラムの実行前に戻す.


      {
       int oldtop = lua_gettop(L);
       lua_dofile(L, filename);
       lua_settop(L, oldtop);
      }

5.9 Luaでの大域変数の扱い

次の関数を用いて,Lua の大域変数の値を得ることができる.


       void lua_getglobal (lua_State *L, const char *varname);

この関数は,引数で指定された変数の値をスタックに入れる. Luaと同様に,この関数は getglobal イベントのタグ関数を呼ぶ (4.7節参照). タグ関数を呼ぶこと無しに,大域変数の値を知るには,大域変数のテーブルに 対して lua_rawget 関数を用いる(以下参照).

大域変数に値を設定するには,次の関数を用いる.


       void lua_setglobal (lua_State *L, const char *varname);

この関数はスタックから値を取り出し,それを大域変数の値に設定する. Luaと同様に,この関数は setglobal イベントのタグ関数を呼ぶ(4.7節参照). タグ関数を呼ぶこと無しに,大域変数の値を設定するには,大域変数のテーブルに 対して lua_rawget 関数を用いる.

大域変数は全て Lua の通常のテーブルとして保持されており, そのテーブルは次の関数で得ることができる.


       void lua_getglobals (lua_State *L);

この関数は現在の大域変数のテーブルをスタックに入れる. 大域変数のテーブルを指定のテーブルで置き換えるには,以下の関数を用いる.


       void lua_setglobals (lua_State *L);

この関数はスタックからテーブルを取り出し,新しい大域変数のテーブルとして 設定する.

5.10 Luaでのテーブルの扱い

Lua のテーブルも,APIを通して扱うことができる.

テーブル中の値を読むためには,スタック中にテーブルを置いて次の関数を呼ぶ. ここで index はテーブルを参照する変数である.


       void lua_gettable (lua_State *L, int index);

lua_gettable はスタックからキーを取り出し,キーで参照されるテー ブルの中身をスタックに入れる. Lua と同様に,この操作は gettable イベントのタグ関数を呼ぶ. タグ関数を呼ぶこと無しにキーで参照されるテーブル中の値を知るには, 以下の ``raw'' の関数を用いる.


       void lua_rawget (lua_State *L, int index);

スタック中に存在するテーブルに値を格納するには,キーと値を(この順に)ス タックに入れ,以下の関数を実行する.


       void lua_settable (lua_State *L, int index);

ここで index はスタック中のテーブルの位置を示す. lua_settable はスタックからキーと値を取り出す. Lua と同様に,この操作は settable イベントのタグ関数を呼ぶ. タグ関数を呼ぶこと無しにテーブル中のキーで示される位置に値を代入する には,以下の ``raw'' の関数を用いる.


       void lua_rawset (lua_State *L, int index);

最後に,以下の関数は新しく空のテーブルを作り,スタックに入れる.


       void lua_newtable (lua_State *L);

5.11 テーブルを配列として用いる

以下の関数を用いることで,Lua のテーブルを配列として扱うことができる. 配列とは数値のみで索引づけされるテーブルである.


       void lua_rawgeti (lua_State *L, int index, int n);
       void lua_rawseti (lua_State *L, int index, int n);
       int  lua_getn    (lua_State *L, int index);

lua_rawgeti 関数は, index で示される位置にあるテーブルの n 番目の要素を取り出す.

lua_rawseti 関数は, index で示される位置にあるテーブルの n 番目に,スタックの一番上の値を入れる.

lua_getn index で示される位置にあるテーブルの要素の数 を返す.この要素数は,テーブルのフィールド n の値(数値の値を持つ 場合)である.そうでないときは,テーブル中で nil でない値を持つ最も大き い数値のインデクスである.

5.12 Luaの関数を呼ぶ

Lua 中で定義された関数(および Lua中で登録された C 言語の関数)は,以下 の手順で Lua を組み込んだプログラムからも呼ぶことができる.はじめに, 呼びたい関数をスタックに入れる.次に,関数への引数を 順番に(1つ目 の引数を1番最初に)スタックへ入れる(5.4節参照).最後に,以下の関数 を実行する.


       int lua_call (lua_State *L, int nargs, int nresults);

この関数は lua_dostring と同じエラー番号を返す(5.7節参照). エラー番号を返すのではなくエラーを伝搬させたい場合は,次の関数を呼ぶ.


       void lua_rawcall (lua_State *L, int nargs, int nresults);

これらの関数で, nargs はスタックに入れた引数の数である.すべての 引数と関数はスタックから降ろされ,実行結果がスタックに入れられる.実行 結果の数は nresults に調整される(4.2節参照).ただし, nresults LUA_MULTRETに等しい場合は, すべての実行結果 がスタックに入れられる.実行結果は順番に(1つ目の結果が1番最初に)スタッ クに入れられ,最終的には最後の結果がスタックの一番上となる.

Lua を組み込むプログラムで以下の Lua の関数呼び出しと等価の処理を行う例を示す.


      a,b = f("how", t.x, 4)

C では,以下のようになる.


    lua_getglobal(L, "t");                /* 大域変数 t (後で用いる) */
    lua_getglobal(L, "f");                           /* 実行する関数 */
    lua_pushstring(L, "how");                        /* 1番目の引数 */
    lua_pushstring(L, "x");                     /* 文字列 `x' を積む */
    lua_gettable(L, -4);        /* t.x の実行結果を積む(2番目の引数) */
    lua_pushnumber(L, 4);                            /* 3番目の引数 */
    lua_call(L, 3, 2);       /* 引数が3つ,返り値が2つの関数を実行 */
    lua_setglobal(L, "b");                      /* 大域変数 b を設定 */
    lua_setglobal(L, "a");                      /* 大域変数 a を設定 */
    lua_pop(L, 1);                         /* t をスタックから降ろす */

注意: このプログラムは,実行後のスタックの状態は実行前の状態と同じであ り,「収支があっている」と言われる.これは良いプログラムの例である.

Lua のいくつかの関数は,独自の C 言語インタフェースを持つ.次の関数を C のプログラム中で実行すると,Lua でのエラーが発生する.


      void lua_error (lua_State *L, const char *message);

この関数を実行しても処理は戻らない.Lua から実行された C のプログラム 中で lua_error が実行された場合は,Lua のプログラム中でエラーが 起こった場合と同様に Lua の実行が終了する.そうでなければ, ext(EXIT_FAILURE) が呼びだされ,プログラムは終了する.終了する 前に, message はエラー処理関数 _ERRORMESSAGE に渡される (4.6節参照). message が NULL の場合は, _ERRORMESSAGE は実行されない.

タグ関数は,以下の関数で変更することができる.


      void lua_settagmethod (lua_State *L, int tag, const char *event);

2番目の引数はタグを指定し,3番目の引数ではイベント名(4.7節参照) を指定する.新しいタグ関数がスタックから降ろされ,古いタグ関数が入れら れる.現在のタグ関数を得たい場合には,以下の関数を用いる.


      void lua_gettagmethod (lua_State *L, int tag, const char *event);

タグの間ですべてのタグ関数を複製するには,以下の関数を用いる.


      int lua_copytagmethods (lua_State *L, int tagto, int tagfrom);

この関数は tagto を返す.

テーブルの要素を順に見るには,以下の関数を用いる.


       int lua_next (lua_State *L, int index);

index は対象となるテーブルの位置を示す.この関数はスタックからキー を取り出し,次のキーと値の対をスタックに入れる.テーブルの要素が尽きる と,この関数は 0 を返す(スタックには何も入れない).例えば以下のように 用いる.


       /* テーブルはスタック中のインデクス t で示される位置にある */
       lua_pushnil(L);  /* 1つ目のキー */
       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)));
         lua_pop(L, 1);  /* value を取り除く.次回の繰り返しのため,index はそのまま */
       
       }

以下の関数はスタックのはじめの n 個を取り出し,接続した結果をス タックに入れる.


       void lua_concat (lua_State *L, int n);

n は少なくとも 2 でなければならない. 接続は Lua の通常の方法で行われる(4.5.4節参照).

5.13 Cの関数を定義する

C 言語の関数を Lua に登録するには,以下のマクロが便利である.


       #define lua_register(L, n, f) (lua_pushcfunction(L, f), lua_setglobal(L, n))
       /* const char *n;   */
       /* lua_CFunction f; */

Lua 中でのその関数の名前と,関数へのポインタを引数に指定する. このポインタは lua_CFunction 型である必要がある. lua_CFunction 型は以下のように定義される.


       typedef int (*lua_CFunction) (lua_State *L);

これは Lua 環境を引数とし,返り値が整数であるような関数へのポインタで ある.

Lua の操作を正しく行うためには,C の関数は次の規則に従って引数と 結果を扱う必要がある.C の関数がスタック上で Lua から引数を受け取る際 には,引数の順にスタックに入れられる(1番目の引数が1番最初に)入れられ る.Lua に値を返す際には,値を順にスタックに入れ,値の数を返り値とする. Lua の関数と同様に,Lua から呼ばれた C の関数も複数の値を返すことがで きる.

例として,以下の関数は可変の数の数値を引数として,それらの平均と合計を 返す.


       static int foo (lua_State *L) {
         int n = lua_gettop(L);    /* 引数の数 */
         double sum = 0;
         int i;
         for (i = 1; i <= n; i++) {
           if (!lua_isnumber(L, i))
             lua_error(L, "incorrect argument to function `average'");
           sum += lua_tonumber(L, i);
         }
         lua_pushnumber(L, sum/n);        /* 1番目の結果 */
         lua_pushnumber(L, sum);          /* 2番目の結果 */
         return 2;                            /* 結果の数 */
       }

この関数を ` average' という名前の Lua の関数として登録するには, 次のようにする.


       lua_register(L, "average", foo);

C の関数が作られたとき, 上位値を対応づけることができ(4.6節参 照), C 閉包 を形成する.それらの値は関数が呼ばれる際に,共通の引 数として関数に渡される.upvalue を C の関数に対応づけるには,それらの 値をスタックに入れ,次の関数を用いて C の関数をスタックに入れる.


       void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);

ここで n は対応づけられる上位値の数である. n 個の値がスタッ クから取り出される. lua_pushcfunction lua_pushcclosure n を 0 にすることで定義している.実際に C の関数が呼ばれたときには,呼び出し時に与えられた引数の後に,対応づけ られた upvalue が 最後の引数として挿入される.これにより,関数は上 位値を受け取る際に,引数の数を気にする必要がなくなる(Lua の関数は任意 の数の引数を受け取れることに注意). i 番目の上位値は, n を 上位値の数として,スタックの位置 i-n+1 にある.

C の関数と閉包の例は,Lua が配布された際に含まれるファイル baselib.c liolib.c lmathlib.c lstrlib.c を 参照せよ.

5.14 Lua オブジェクトの参照

C 言語のプログラム中で,Lua の値を関数の生存期間を越えて保持する必要が ある場合は,値への 参照を作る必要がある.参照を扱う関数としては, 次のものがある.


       int   lua_ref    (lua_State *L, int lock);
       int   lua_getref (lua_State *L, int ref);
       void  lua_unref  (lua_State *L, int ref);

lua_refはスタックから値を取り出し,その値への参照を生成して返す. nil という値への参照は常に LUA_REFNIL である.定数 LUA_NOREFは正しい参照のどれとも異なる. lock が true であれば, そのオブジェクトは 固定され,ガーベジコレクションの対象にはならな い. 固定されていない参照はガーベジコレクションの対象となる

C 言語中で参照されるオブジェクトが必要になったときは, lua_getref 関数を実行すればオブジェクトがスタックに入れられる.オ ブジェクトがガーベジコレクトされた場合には, lua_getref は 0 を 返し,スタックには何も入れられない.

参照が不要になった時には, lua_unref で解放する必要がある.

レジストリ

Lua が起動したときには, LUA_REFREGISTRY で示される位置にテーブ ルを登録する.このテーブルを操作するには次のマクロを用いる.


       #define lua_getregistry(L)      lua_getref(L, LUA_REFREGISTRY)

このテーブルは一般的なレジストリ操作の方法で C ライブラリによって操作 できる.どの C ライブラリもこのテーブルにデータを保存できる.ただし 他のライブラリとキーが異なる必要がある.

6. 標準ライブラリ

標準ライブラリが提供するのは,標準 API を直接用いて実装された有用な関 数群である.従って言語そのものにとって必須ではなく,独立した C のモジュー ルとして提供される.現在,Lua には以下の標準ライブラリがある.

これらのライブラリを利用するためには,C のプログラムは初めに lua_baselibopen lua_strlibopen lua_mathlibopen lua_iolibopen を実行する必要がある.これらの関数は lualib.h 中で定義されている.

6.1 基本関数

基本ライブラリは Lua にいくつかの重要な機能を提供する.従って基本ライ ブラリを利用しない応用ソフトウェアを作成する場合は,これらの機能の代用 を何らかの形で提供する必要がないか,注意する必要がある (例えば _ERRORMESSAGE関数が無ければ,Lua は エラーメッセージを 表示できない).


_ALERT (message)

引数の文字列を標準エラー出力に出力する.Lua のすべてのエラーメッセーは この大域変数 _ALERT に代入された関数を通して出力される (4.6節参照). この変数に他の関数を対応づけることにより,メッセージの出力方法を変える ことができる(例えば標準エラー出力が無いシステム等).


assert (v [, message])

v nil の場合には,"assertion failed" のエラーを生じる. この関数は以下の Lua 関数と等価である.


      function assert (v, m)
         if not v then
           m = m or ""
           error("assertion failed!  " .. m)
         end
       end


call (func, arg [, mode [, errhandler]])

関数 func をテーブル arg で与えられる引数で呼び出す. この呼び出しは以下と等価である.


       func(arg[1], arg[2], ..., arg[n])

ここで n getn(arg) の結果である(6節参照). call func のすべての実行結果を返す.

初期設定では, func の呼び出しにエラーが生じた場合には,エラーは 伝搬する.文字列 mode が "x" を含む場合には,この呼び出しは 保護されており,呼び出し中に何が起こっても call はエラーを伝 搬しない.代わりにエラーが起こったことを知らせるために nil を返す (適当なエラー処理関数を呼ぶ場合を除く).

errhandler が与えられた場合には, func を実行している間は エラー関数 _ERRORMESSAGE が一時的に errhandler に設定され る.特に errhandler nil の場合には,関数の呼び出し中に エラーメッセージは出されない.


collectgarbage ([limit])

ガーベジコレクションのしきい値を指定の値に設定し(キロバイト単位),Lua が現在使用している動的メモリのバイト数と比較される.指定したしきい値がこ のバイト数以下の場合にはガーベジコレクションがすぐに実行される (5.5節参照). limit が省略された場合は 0 となり,ガーベジコレ クションが強制的に実行される.


copytagmethods (tagto, tagfrom)

あるタグから別のタグへすべての関数を複製する. tagto を返す.


dofile (filename)

引数で指定されるファイルを開き,Lua のプログラムかまたは事前コンパイル 済のプログラムとして実行する.引数が与えられない場合には,標準入力 の内容を実行する.ファイルの実行中にエラーが生じた場合には, dofile nil を返す.エラーが無かった場合には,プログラムの 実行結果を返す.プログラムが値を返さない場合には, nil でない値を 返す.引数が文字列以外の場合にはエラーとなる.


dostring (string [, chunkname])

引数で指定される文字列を Lua のプログラムとして実行する. 実行中にエラーが生じた場合には, dostring nil を返す. エラーが無かった場合には,プログラムの実行結果を返す.プログラム が値を返さない場合には, nil でない値を返す. 任意の引数 chunkname はチャンクの名前であり,エラーメッセー ジやデバッグ時の情報として使用される. dostring は API 関数 lua_dostring と等価である.


error (message)

エラー処理関数を呼び出し(4.6節参照), 最後に呼ばれた保護された関数 (C 言語では lua_dofile lua_dostring lua_dobuffer lua_callfunction. Luaでは dofile dostring,保護モードでの call). を終了させる. message nil の場合には,エラー処理関数は呼ばれない. 関数 error を呼び出すと処理は戻らない.


foreach (table, func)

指定された関数 func table の各要素に対して実行する. 関数はインデクスと要素の値を引数として実行される.関数が nil でない値を返した場合は,繰り返しはそこで終了し,その値が foreach の返り値になる.

Lua の関数として以下のように定義することもできる.


      function foreach (t, f)
         for i, v in t do
           local res = f(i, v)
           if res then return res end
         end
       end

テーブル _t を途中で変更した場合の foreach の振舞いは 未定義である.


foreachi (table, func)

指定された関数 func table の各数値のインデクスに対して 実行する.関数はインデクスと対応する要素の値を引数として実行される. インデクスは 1 から n まで順番に用いられる.ここで n getn(table) の返り値である(6節参照). 関数が nilでない値を返した場合は,繰り返しはそこで終了し,その値 が foreachi の返り値になる. Lua の関数として以下のように定義することもできる.


       function foreachi (t, f)
         for i=1,getn(t) do
           local res = f(i, t[i])
           if res then return res end
         end
       end


getglobal (name)

大域変数の値を得るか,または getglobal タグ関数を呼び出す. 4.7節で詳しく説明する.文字列 name は構文的に 正しい変数名でなくてもよい.


getn (table)

テーブルをリストと見なしたときの大きさを返す. テーブルの n フィールドが数値の場合,その値が返される.そうでな ければ,テーブル中で nil 以外の要素に対応する最大の数値インデクスが 返される.Lua の関数として以下のように定義することも可能である.


       function getn (t)
         if type(t.n) == "number" then return t.n end
         local max = 0
         for i, _ in t do
           if type(i) == "number" and i>max then max=i end
         end
         return max
       end


gettagmethod (tag, event)

引数で指定される (タグ,イベント) に対応するタグ関数を返す. この関数は gc イベントに対応するタグ関数を得るために用いることはできな い(それらのタグ関数は C 言語からのみ操作できる).


globals ([table])

現在の大域変数のテーブルを返す.引数 table を指定した場合は, さらにそのテーブルを大域変数のテーブルに設定する.


newtag ()

新しいタグを返す.


next (table, [index])

指定されたテーブルのフィールドを順番に得る.1番目の引数はテーブル,2 番目の引数はそのテーブルのインデクスを指定する. next はテーブル の次のインデクスと対応する要素を返す.2番目の引数として nil が 指定された場合には,テーブルの最初のインデクスと対応する要素を返す.テー ブルの最後のインデクスが指定された場合や空のテーブルで nil が 指定された場合には, nil を返す.2番目の引数が指定されない場合は nil とされる

Lua にはフィールドの宣言が無く,テーブル中に存在しないフィールドと nil を値として持つフィールドは同様に扱われる.したがって, next nil でない値を持つフィールドのみ扱うことができる. インデクスを取り出す順序は規定されていない.これは インデクスが数値であっても同様である (数値順に取り出したい場合には,数値用の for または foreachi 関数を用いよ).


print (e1, e2, ...)

任意個の引数について, tostring で返される値を表示する. この関数は形式を指定した表示ではなく,デバッグ等のために素早く値を表示 するための関数である.表示形式の指定については6.3節を参照せよ.


rawget (table, index)

タグ関数を呼ぶこと無しに table[index] の値を得る. table はテーブル, index nil 以外の値を指 定する.


rawset (table, index, value)

タグ関数を呼ぶこと無しに, table[index] の値を value に設定 する. table はテーブル, index nil 以外の値, value は任意の Lua における値を指定する.


setglobal (name, value)

指定された名前の大域変数を指定された値に設定するか,setglobal タグ関数 が呼ばれる.詳しい説明は 4.7節 で述べる. 文字列 name は構文的に正しい変数名でなくてもよい.


settag (t, tag)

指定されたテーブルのタグを設定する(2節参照). tag newtag 関数で生成された値を指定する (6節参照).この関数は1番目の引数(テーブル)の値を返す. Lua を組み込むプログラムの安全のため,Lua 中のユーザデータのタグを 変更することはできない.


settagmethod (tag, event, newmethod)

指定された (タグ,イベント) に対して新しいタグ関数を設定し,古いタグ関 数を返す. newmethod nil の場合には,指定されたイベント に対する初期設定時の振舞いに戻す.


sort (table [, comp])

テーブル中の要素を table[1] から table[n] まで指定された順 序に その場で並べかえる. ここで n getn(table) の返り値である(6節参照) comp を指定する場合には,テーブル中の2つの要素を引数とし, 1つ目の要素が2つ目より小さいとき真( nil 以外の値)を返す関数とす る(よって並べかえ後には not comp(a[i+1], a[i]) が真となる). comp が指定されない場合には,Lua の演算子 < が用いられる.

並べかえのアルゴリズムは安定ではない(指定された順序で等しいとされた要 素の前後関係は,並べかえ後に保存されない).


tag (v)

値のタグを得る(2節参照).1つの引数を指定し,タグ(1つの数値)を 返す. tag は API 関数の lua_tag と等価である.


tonumber (e [, base])

指定された引数の数値への変換を試みる.引数が数値または数値と互換性のあ る文字列の場合は,その数値を返す.そうでなければ nilを返す.

任意の引数 base は,数値の基数を指定する. 基数は 2 以上 36 以下の任意の整数である. 10 以上の基数の場合には,A (大文字,小文字どちらも可)が 10 を表し, B が 11 を表し,以下同様である.Z は 35 を表す.

基数が 10 の場合( base を省略した場合)には,指数部があっても良い (4.1節参照).他の基数の場合には,符合無し整数のみを扱うことができる.


tostring (e)

任意の型の引数を指定し,通常の方法で文字列に変換する. 数値を文字列に変換する方法を細かく指定する場合には, format 関数 を用いよ.


tinsert (table [, pos] , value)

要素 value をテーブルの位置 pos に挿入する.必要に応じて 他の要素を空いている位置へずらす. n getn(table) の返り値としたとき, 指定されない場合の pos n+1 とされ(6節参照), tinsert(t,x) x をテーブル t の最後に挿入する. この関数はテーブルの n フィールドを n+1 に設定する. テーブルの要素の参照が raw (タグ関数が呼ばれない) ことを除き, tinsert は以下の Lua 関数と等価である.


       function tinsert (t, ...)
         local pos, value
         local n = getn(t)
         if arg.n == 1 then
           pos, value = n+1, arg[1]
         else
           pos, value = arg[1], arg[2]
         end
         t.n = n+1;
         for i=n,pos,-1 do
           t[i+1] = t[i]
         end
         t[pos] = value
       end


tremove (table [, pos])

テーブル table から位置 pos の要素を除く. 必要に応じて他の要素を空いた位置へずらす. n getn(table) の返り値としたとき, 指定されない場合の pos n+1 とされ(6節参照), tremove(t) はテーブル t の最後の要素を削除する. この関数はテーブルの n フィールドを n-1 に設定する.

テーブルの要素の参照が raw (タグ関数が呼ばれない) ことを除き, tremove は以下の Lua 関数と等価である.


       function tremove (t, pos)
         local n = getn(t)
         if n<=0 then return end
         pos = pos or n
         local value = t[pos]
         for i=pos,n-1 do
           t[i] = t[i+1]
         end
         t[n] = nil
         t.n = n-1
         return value
       end


type (v)

v の型を文字列として返す. この関数の返り値は, "nil"( nil という値ではなく文字列), "number" "string" "table" "function" "userdata"のいずれかである.

6.2 文字列の操作

このライブラリは,部分文字列の発見や抽出やパターンマッチ等,文字列の一 般的な操作を提供する.文字列のインデクスは C 言語とは異なり,はじめの 文字のインデクスは 1 である.またインデクスが負の場合は文字列の最後か ら逆方向に数える.インデクス -1 は最後の文字を表す.


strbyte (s [, i])

文字 s i 番目の文字の内部数値コードを返す. i が指定されないときには 1 とされる. i は負でもよい.

注意: 内部数値コードは処理系に依存して異なる場合がある.


strchar (i1, i2, ...)

0 以上の個数の整数を引数に指定し,各引数を内部数値コードとする文字から なる文字列を返す.

注意: 内部数値コードは処理系に依存して異なる場合がある.


strfind (s, pattern [, init [, plain]])

s 中で pattern に最初に マッチする部分文字列を検索する. 見つかった場合には, s 中の開始位置と終了位置を返す.見つからなけ れば nil を返す.パターンがキャプチャ(以下の gsub 関数を参 照)を含む場合には,キャプチャにマッチした文字列も返り値に追加される. 3番目の引数 init は検索をどの位置から始めるか指定する. init は負であってもよく,指定がない場合は 1 が用いられる. 4番目の引数に 1 を指定すると,パターンマッチを行わず,単なる部分文字 列の検索を行う.その際には pattern 中のどの文字も特殊文字として 扱われない. plain を指定する時には init は省略できないこと に注意.


strlen (s)

指定された文字列の長さを返す.空文字列 "" の長さは 0 である.文字列中 の埋め込まれたゼロも長さに数えられ,"a¥¥000b¥¥000c" の長 さは 5 になる.


strlower (s)

指定された文字列中を複製し,文字列中の大文字を小文字に変換して返す. その他の文字は変更されない.大文字の定義はロカールに依存する.


strrep (s, n)

文字列 s の複製を n 個接続した文字列を返す.


strsub (s, i [, j])

文字列 s の位置 i から j までの部分文字列の複製を返 す. i および j は負でもよい. j が指定されない場合は, -1 とされる(文字列の長さが指定されたのと同じ).特に, strsub(s,1,j) は文字列 s の先頭の j 文字を返し, strsub(s,-i) は末尾 i 文字を返す.


strupper (s)

指定された文字列中を複製し,文字列中の小文字を大文字に変換して返す. その他の文字は変更されない.小文字の定義はロカールに依存する.


format (formatstring, e1, e2, ...)

1番目の引数(文字列)に従って,残りの任意の個数の引数を整形して返す. formatstring は C 言語の printf 族の関数に従う.異なる点は *, l, L, n, p の変換には対応しておらず, q 変換 が導入されたことである. q 変換は文字列を Lua インタプリタ が安全に扱える形式に変換する.二重引用符の間にある文字や二重引用符や改 行やバックスラッシュは,すべて書かれたとき正しくなるようにエスケープさ れる.例えば,以下の呼び出しは,


       format('%q', 'a string with "quotes" and ¥n new line')

以下を生成する.


"a string with ¥"quotes¥" and ¥
new line"

引数の順番に従って整形するのではなく,整形の際に明示的に引数の位置を指 定することもできる.その際には,変換を表す文字 % の代わりに が用いられる.ここで d は [1,9] の範囲の整数で あり,引数の位置を表す.例えば, format("%2$d -> %1$03d", 1,34)"34 -> 001" となる.同一の引数を何回も用いることもできる.

c, d, E, e, f, g, G, i, o, u, X, x の変換は数値引数を取り, q, s は文字列を引数に取る. * 修飾子は適切な書式を作ること で同様な変換を行うことができる.例えば "%*g""%"..width.."g" と同等である.

注意: formatstring %s で整形される文字列引数に 埋め込まれたゼロが含まれていてはならない. %q はそのような 文字列を扱うことができる.


gsub (s, pat, repl [, n])

文字列 s を複製し, pat の出現を全て repl で置き換 えたものを返す.この関数は2つ目の返り値として,行った置換の数を返す.

repl が文字列の場合には,その文字列で置換を行う. repl中の %n ( n は 1 から 9 の数値) は n 番目のキャプチャを表す.

repl が関数の場合には,マッチングが起こるたびに関数が呼ばれ, マッチした文字列が順に引数として渡される(以下参照).関数の返り値が 文字列の場合には,その文字列で置換を行う.他の場合には,空文字列で置換 が行われる.

最後に,任意指定の引数 n は最大の置換回数を指定する.例えば, n が 1 の時は pat の最初の出現のみ置換される.


   x = gsub("hello world", "(%w+)", "%1 %1")
   --> x="hello hello world world"

   x = gsub("hello world", "(%w+)", "%1 %1", 1)
   --> x="hello hello world"

   x = gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
   --> x="world hello Lua from"

   x = gsub("home = $HOME, user = $USER", "%$(%w+)", getenv)
   --> x="home = /home/roberto, user = roberto"  (for instance)

   x = gsub("4+5 = $return 4+5$", "%$(.-)%$", dostring)
   --> x="4+5 = 9"

   local t = {name="lua", version="4.0"}
   x = gsub("$name - $version", "%$(%w+)", function (v) return %t[v] end)
   --> x="lua - 4.0"

   t = {n=0}
   gsub("first second word", "(%w+)", function (w) tinsert(%t, w) end)
   --> t={"first", "second", "word"; n=3}


パターン


文字クラス:
文字クラスは文字の集合を表すのに用いられる. 文字の種類を表現するために,以下の記述を用いる.


x    (x が ^$()%.[]*+-? のどの文字でもない場合) 文字 x そのものを表す
.    (ピリオド)任意の文字を表す.
%a   全てのアルファベット文字を表す.
%c   制御文字を表す.
%d   数値を表す.
%l   小文字を表す.
%p   句読点を表す.
%s   空白文字を表す.
%u   大文字を表す.
%w   アルファベットまたは数値を表す.
%x   16進数の数値を表す.
%z   ゼロで表現される文字を表す.
%x   (x はアルファベットや数でない文字) x そのものを表す.これは特殊文字
     をエスケープする標準的な手法である.パターン中のすべての句読点は(特
     殊文字でなくても),% をつけるべきである.

[文字の集合]   文字集合に含まれる全ての文字の和集合を表す.文字の範囲指定
     は,最初の文字と最後の文字を - でつなぐことで表す.上記の %x の形式の
     記述はすべて文字集合の要素として用いることができる.他の全ての文字は,
     文字そのものを表す.例えば, [%w_] (または  [_%w]) は,全てのアルファ
     ベットまたは数値文字を表し,[0-7] は8進数の数字を表し,[0-7%l%-] は
     8進数の数値と小文字と - を表す.
     範囲指定と文字クラスの組み合わせは定義されていない.よって,[%a-z] や
     [a-%%] は意味を持たない.

[^文字集合]   文字集合の補集合を表す.文字集合は上記と同様に解釈される.

%a, %c 等の英字1文字で表される文字集合では,対応する文字 の大文字はその補集合を表す.例えば, %S は空白でない文字を表す.

アルファベット,空白,等の定義はロカールに依存する.とりわけ, [a-z] %l に一致するとは限らない.移植性を考えると,後者を用いるべきで ある.


パターン要素:
パターン要素は,


パターン:
パターンはパターン要素の系列である.パターン先頭の ^ は対象文字列の先頭にマッチする.パターン最後の $ は対象文字列の 最後にマッチする.パターン中の他の位置に置かれた場合は,^ $ は特別な意味を持たず,それ自身を表す.


キャプチャ:
パターン中には括弧で囲まれたパターンが含まれていてもよい.これは キャプチャと呼ばれる.マッチングが起こった場合には,キャプチャの 部分にマッチした文字列は保存され,後で用いることができる.キャプチャは 左括弧に対応する番号がつけられる.例えば, "(a*(.)%w(%s*))" というパターン中で, "a*(.)%w(%s*)" にマッチする文字列は1番目のキャプチャ (番号1で表される)であり, . にマッチする文字は番号2で表される. 同様に %s* にマッチする文字列は番号3となる.

注意: パターンは埋め込まれたゼロを含んではならない.代わりに %z を用いよ.

6.3 数学関数

このライブラリは C 言語の標準的な数学関数のインタフェースである.ただ し,2項演算子 にタグ関数が追加されている.数値 x^ yに適用されると x^y を返す.

このライブラリは以下の関数と大域変数 PI を提供する.


       abs  acos  asin  atan  atan2  ceil  cos  deg    floor  log     log10
       max  min   mod   rad   sin    sqrt  tan  frexp  ldexp  random  randomseed

ほとんどの関数は C の数学ライブラリの同名の関数のインタフェースであ る.例外は三角関数で,引数はラジアンではなくで表す. deg 関数と rad 関数を用いてラジアンと度の間の変換をするこ とができる.

max 関数は数値引数に対して最大値を返す.同様に min 関数は 最小値を返す.両方とも 1 個,2個,またはそれ以上の引数を取ることがで きる.

random 関数と randomseed 関数は,ANSI C で提供される単純な 乱数生成関数 rand srand へのインタフェースである (乱数の統計的性質に関しては保証はされない).引数無しでよばれた時, random 関数は [0,1) の間の疑似乱数を返す.引数として 数値 n が与えられた時,[1, n] の間の疑似乱数を返す. 引数として2つの数値 l u が与えられた時, [ l,u] の間の疑似乱数を返す.

6.4 入出力関数

初期設定時には Lua のすべての入出力は,読み込みと書き出しに対応する2つ の ファイルハンドラを通じて行われる.ファイルハンドラは Lua の大 域変数 _INPUT _OUTPUT に保持されている. また大域変数 _STDIN, _STDOUT, _STDERR はそれぞれ ファイル記述子 stdin, stdout, stderr で初期化されている. 初期設定では, _INPUT = _STDIN _OUTPUT=_STDOUT である.

ファイルハンドラは FILE * ストリームを含むユーザデータであり, 入出力関数によって特別なタグ関数が付与される.

特に明記されない場合には,入出力関数は失敗したとき nil を返し そうでなければ nil 以外の値を返す.


openfile (filename, mode)

文字列 mode で指定されるモードでファイルを開き,ファイルハンドラ を返す.失敗した場合には nil に加えエラーの説明を記述した文字列 を返す. _INPUT _OUTPUT を変更しない.

文字列 mode は以下の1つを指定する.


``r'' 読み込みを行う.
``w'' 書き出しを行う.
``a'' 追加を行う.
``r+'' 更新を行う.以前のデータは残される.
``w+'' 更新を行う.以前のデータは消去される.
``a+'' 追加更新を行う.以前のデータは残される.書き込みはファイル の最後からのみ可能である.

mode の最後に b を加えてもよい.システムによってはバイ ナリファイルを開く際に必要となる. mode は C の標準的な関数 fopen で用いられるものと完全に同一である.


closefile (handle)

指定されたファイルを閉じる. _INPUT _OUTPUT を変更しない.


readfrom (filename)

この関数は2通りの方法で用いられる.引数にファイル名が指定された時は そのファイルを開き,ファイルハンドラを _INPUT に対応づけてファイ ルハンドラを返す.その際,入力ファイルが閉じられることはない. 引数が指定されないときは _INPUT で開かれているファイルを閉じ, 再び stdin を対応づける. 失敗した場合には nil およびエラーの説明を記述した文字列を返す.

注意: filename | で始まる場合には, popen 関数を用いて パイプを介した入力が開かれる.すべてのシステムでパイプが実装されている わけではない.また,同時に開くことのできるファイル数には通常上限があり, その数はシステムによって異なる.


writeto (filename)

この関数は2通りの方法で用いられる.引数にファイル名が指定された時は そのファイルを開き,ファイルハンドラを _OUTPUT に対応づけてファ イルハンドラを返す.その際,出力ファイルが閉じられることはない. 引数が指定されないときは _OUTPUT で開かれているファイルを閉じ, 再び stdout を対応づける. 失敗した場合には nil およびエラーの説明を記述した文字列を返す.

注意: filename | で始まる場合には, popen 関数を用いて パイプを介した入力が開かれる.すべてのシステムでパイプが実装されている わけではない.また,同時に開くことのできるファイル数には通常上限があり, その数はシステムによって異なる.


appendto (filename)

filename で指定されるファイルを開き, _OUTPUT に対応づける. writeto とは異なり,以前のファイルの内容を消すことはない. 書かれた内容はファイルの最後に追加される. 失敗した場合には, nil およびエラーの説明を記述した文字列を返す.


remove (filename)

filename で指定されるファイルを消去する. 失敗した場合には, nil およびエラーの説明を記述した文字列を返す.


rename (name1, name2)

name1 というファイルの名前を name2 に変更する. 失敗した場合には, nil およびエラーの説明を記述した文字列を返す.


flush ([filehandle])

書かれたデータを指定されたファイルに実際に書き出す. filehandle が指定されないときは, flush は開かれている全てのファイルに対して 行われる.失敗した場合には, nil およびエラーの説明を記述した文字 列を返す.


seek (filehandle [, whence] [, offset])

ファイル中での位置(バイト単位)を得たり変更したりする. ファイルの先頭からの位置を offset と, whence で指定される 基準位置との和で指定する. whence の値には以下のような物が指定できる.


``set'' ファイルの先頭(0)を基準にする.
``cur'' 現在の位置を基準にする.
``end'' ファイルの終端を基準にする.

seek はファイル中の最終的な位置をファイルの先頭からバイト単位 で返す.失敗した場合には, nil およびエラーの説明を記述した文字 列を返す.

whence が指定されない場合は "cur" が選択され, offset が指定されない場合は 0 とされる.よって seek(file) はファイ ル中の現在位置を返し,位置の変更は行わない. seek(file, "set") は 位置をファイルの先頭に設定する(そして 0 を返す). seek(file, "end") は位置をファイルの最後に設定する(ファイルの大きさを返す).


tmpname ()

一時的なファイルとして安全に利用できるファイル名を返す. ファイルを使用前に開く操作や使用後に消す操作は明示的に行う必要がある.


read ([filehandle,] format1, ...)

指定された書式で filehandle (指定されない場合は _INPUT) から 読み込む.各フォーマットに対して,読まれた文字列または数値を返す.指定 された書式で読むことができなかった場合は nil を返す.フォーマッ トが指定されない時には,次の一行を読むフォーマットが選択される(以下参 照).

フォーマットには以下の物が指定できる.


``*n'' 数値を1つ読む.数値を返す唯一のフォーマットである.
``*l'' 次の1行を読む(改行は読み飛ばされる).ファイルの終端の 場合には nil が返される.
  フォーマットが指定されない場合にこれが選択される.
``*a'' 現在位置から始めてファイル全体を読み込む.ファイルの 終端の場合には空文字列が
  返される.
``*w'' 次の単語が返される.単語は空白文字以外の繰り返しで最 大長のものである.必要に
  応じて空白は読み飛ばされる.ファイルの終端の場合には nil が返される.
number 最大で指定される数の文字数の文字列を読み込む. ファイルの終端の場合には
  nil が返される.


write ([filehandle, ] value1, ...)

各引数の値を filehandle (指定されない場合は _OUTPUT) に 書き出す.引数は文字列または数値である必要があり,他の型の値を書く場合 には事前に tostring や format を使用する.失敗した場合には, nil およびエラーの説明を記述した文字列を返す.

6.5 システム関数


clock ()

プログラムによって使われた CPU 時間の合計の推定値を秒単位で返す.


date ([format])

format で指定される書式に従い,日付と時間を文字列にして返す. format は ANSI C の関数 strftime と同一の規則に従う. 引数が指定されない場合には,日付と時間をシステムとロカールに応じて 適切な表現にして返す.


execute (command)

C 言語の関数 system と等価である. command は OS のシェルに よって実行される.実行後の終了ステータスを返す(値はシステムに依存する).


exit ([code])

C 言語の関数 exit を呼びプログラムを終了する. code か指定された場合には code exit の引数となり, 指定されない場合には正常終了を示す値が引数となる.


getenv (varname)

実行環境での環境変数 varname の値を返す. varname が未定義 の場合には nil を返す.


setlocale (locale [, category])

ANSI C の setlocale 関数のインタフェースである. locale はロカールを指定する文字列である. category はどのロカールを変更するかを示し, "all", "collate", "ctype", "monetary", "numeric", "time" を指定 する.指定されない場合は "all" が選択される.新しいロカールの名 前が返される.失敗した場合には nil が返される.

7. デバッガインターフェイス

Luaはデバッグを行う機能を直接には提供していない.代わりに関数や フッ クを用いた特別なインタフェースを提供している.これらのインタフェー スを用いてインタプリタ内部の情報を得て,様々なデバッガやプロファイラ等 必要なツールを作ることができる.このインタフェースは luadebug.h 中で定義されている.

7.1 スタックと関数の情報

以下の関数を用いて,インタプリタのスタックの情報を得ることができる.


      int lua_getstack (lua_State *L, int level, lua_Debug *ar);

この関数は,指定されたレベルで実行されている関数の駆動レコード (activation record) と同一のものを lua_Debug に代入する.レベル 0 は現在実行されている関数であり,レベル n+1 はレベル n の関 数を呼び出した関数である. lua_getstack は通常は 1 を返す.現在の スタックの深さよりも大きなレベルが指定された場合は 0 を返す.

lua_Debug 構造体は活性化している関数に関する情報を保持する.


      typedef struct lua_Debug {
        const char *event;     /* "call", "return" */
        int currentline;       /* (l) */
        const char *name;      /* (n) */
        const char *namewhat;  /* (n) global, tag method, local, field */
        int nups;              /* (u) upvalues の数 */
        int linedefined;       /* (S) */
        const char *what;      /* (S) "Lua" function, "C" function, Lua "main" */
        const char *source;    /* (S) */
        char short_src[LUA_IDSIZE]; /* (S) */

        /* private part */
        ...
      } lua_Debug;

lua_getstack 関数はこの構造体の private の要素にのみ値を入れる. 他の要素にも値を入れるには,以下の関数を用いる.


       int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);

この関数はエラーが起こると 1 を返す( what に無効な引数を指定した 場合など). what 文字列の各文字が ar の特定の要素を指定し, その要素に値が入れられる.この文字と要素の対応は,上記の lua_Debug 構造体に示したものである.文字 ` S' は要素 source, linedefined, what を示し, 文字 ` l' は要素 currentline を示す. さらに,文字 ` f' は指定されたレベルで実行されている関数をスタッ クに入れる.

駆動していない関数(スタック上にない関数)についての情報を得るには, 関数をスタックに入れ, what の先頭の文字を > とすればよい. 例えば,関数 f が定義されている行を調べるには,以下のよ うにすればよい.


       lua_Debug ar;
       lua_getglobal(L, "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 part) の場合は文字列 "main" である.


currentline
指定された関数が実行している行を示す.実行している行に関する情報が得ら れない場合には,-1 が代入される.


name
指定された関数の適当な名前である.Lua の関数はファーストクラスの変数 であるため,固定された名前を持たない.関数は大域変数の値であることもあ るし,テーブルの要素として保持されるだけの関数もある. lua_getinfo 関数は指定された関数がタグ関数または大域変数の値であるかを調べる. タグ関数の場合には, name にはイベントの名前を指す. 関数が大域変数の値である場合には,変数の名前を指す. 他の場合には, name には NULL が代入される.


namewhat
上記の name の説明である.関数が大域変数の場合には namewhat "global" である.タグ関数の場合には "tag-method" である.他の場合には "" (空文字列) である.


nups
関数の上位値の数である.

7.2 局所変数の操作

局所変数を操作するため, luadebug.h ではインデクスを用いている. 1番目の局所変数のインデクスは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 で得られたものかフックへの引数とされたものである必 要がある(7.2節参照). lua_getlocal 関数は局所変数のインデクス( n)を指定すると,変 数の値をスタックに積み,変数名を返す. 新しい変数をスタックに積んで lua_setlocal 関数を呼ぶと,指定され た値を変数に代入して変数名を返す. 駆動している変数の数より大きいインデクスを指定したときには,これらの関数 は NULL を返す.

例として,以下の関数はスタックの指定されたレベルに対して,局所変数の名 前の一覧を作る.


       int listvars (lua_State *L, int level) {
         lua_Debug ar;
         int i = 1;
         const char *name;
         if (lua_getstack(L, level, &ar) == 0)
           return 0;  /* 失敗:  スタック中に無いレベルを指定した */
         while ((name = lua_getlocal(L, &ar, i++)) != NULL) {
           printf("%s¥n", name);
           lua_pop(L, 1);  /* 変数の値を除く */
         }
         return 1;
       }

7.3 フック

Lua のインタプリタはデバッグ用に呼び出しフック (call hook) と行フック (line hook) という2つのフックを提供している.これらのフックは以下の型 である.


       typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);

フックを設定するには以下の関数を用いる.


       lua_Hook lua_setcallhook (lua_State *L, lua_Hook func);
       lua_Hook lua_setlinehook (lua_State *L, lua_Hook func);

フックを無効にするには,値として NULL を設定する. 両方のフックの初期値は NULL である. lua_setcallhook 関数と lua_setlinehook 関数は指定されたフッ クを設定し,以前のフックを返す.

呼び出しフックはインタプリタが関数に入る時と出る時に毎回呼ばれる. ar の中の event の値が対応して "call" または "return" に設定される.この ar の値は, lua_getinfo, lua_getlocal, lua_setlocal 関数の引数として用いるこ とができ,関数についての情報を得たり,局所変数を操作したりすることがで きる.

行フックはインタプリタが実行しているプログラムの行を変更した時に毎回 呼ばれる. ar event の値は "line" に, currentline の値は行番号にそれぞれ設定される. 同様に,デバッグ用の関数に対してこの ar の値を指定することができる.

Lua は1つのフックを実行している間には他のフックを実行しない.よってフッ クの内部で関数やチャンクを実行するため Lua を呼び出したとしても, フックに対する呼び出しは行われずに実行される.

7.4 直接的なデバッガインターフェイス

ldblib ライブラリは Lua プログラムにデバッグのインタフェースを提 供する.使用する場合には,まずプログラム中で lua_dblibopen を呼 ぶ必要がある.

このライブラリを用いる際には十分注意する必要がある.以下の関数はデバッ グや類似のタスク (プロファイリング等)に対して排他的に用いなければなら ない.また通常のプログラムの道具として使おうと考えてはならない.これら の関数の実行は遅く,言語の安全性をおびやかす(局所変数の隠蔽等).もしプ ログラム中でこのライブラリを用いないならば, lua_dblibopenを実行 しないこと.


getinfo (function, [what])

この関数は,指定された関数に関する情報のテーブルを返す.関数を直接指 定しても良いし, function の値として数値を指定しても良い. function に数値を指定した場合,スタックの function レベル で実行されている関数を意味する.レベル 0 は現在実行されている関数 ( getinfo そのもの),レベル 1 は getinfo を呼び出した関数, 等々.活性化している関数の数よりも大きな function の値を指定した 場合には, getinfo nil を返す.

返り値のテーブルは lua_getinfo で返されるすべての要素を含み, what によって要素を指定することができる.指定しない場合はすべて の要素となる.

例えば, getinfo(1,"n").name は現在の関数の名前(適当な名前が存在 する場合)を返し, getinfo(print) print 関数について得ら れる全ての情報を含むテーブルを返す.


getlocal (level, local)

この関数は, level で指定されるレベルの関数の local で指定 される変数の名前と値を返す(1番目の引数のインデクスは1であり,最後の 駆動している局所変数まで順番である).指定されたインデクスに対応する局所 変数が無い場合には nil を返す.また指定された level が範囲 外の値の場合にはエラーとなる( getstack 関数を用いることで値が正 しいかどうかを確かめることができる).


setlocal (level, local, value)

この関数は, level で指定されるレベルの関数の local で指定 される変数に対し,値 value を代入する. 指定されたインデクスに対応する局所変数が無い場合には nil を返す. また指定された level が範囲外の値の場合にはエラーとなる.


setcallhook (hook)

関数 hook を呼び出しフックに設定する. このフックはインタプリタが関数に入る時と出る時に毎回呼ばれる. フックの引数は1つであり,イベント名( "call" または "event") が与えられる. レベルを2として getstack 関数を呼ぶことにより,問題の関数の情報 を得ることができる(レベル 0 は getstack 関数,レベル 1 は setcallhook 関数である). 引数を指定せずに呼んだ場合,行フックを無効にする. setcallhook は以前のフックを返す.


setlinehook (hook)

関数 hook を行フックに設定する.このフックはプログラム中のインタ プリタが実行している行が変わる時に毎回呼ばれる.フックの引数は1つで あり,インタプリタが実行しようとしている行の番号が与えられる. 引数を指定せずに呼んだ場合,行フックを無効にする. setlinehook は以前のフックを返す.

8. 単独のLuaインタプリタ

本来 Lua は C プログラムに埋め込まれて使われる拡張言語として設計されて いる.しかし,独立した言語として用いられることも多い.独立した言語とし ての Luaのインタプリタ(単に lua と呼ばれる)は,Lua の標準的な 配布に含まれる. lua には以下の引数を指定することができる.


-sNUM スタックの大きさを NUM にする.指定する場合には引数の先頭で指定 する必要がある.
- 標準入力をファイルとして実行する.
-c すべての引数を実行し終えた後に lua_close を呼ぶ.
-e stat 文字列 stat を実行する.
-f ファイル テーブル arg 中の残りの引数でファイルを実行する.
-i プロンプトを表示する対話モードで実行する.
-q プロンプトを表示しない対話モードで実行する.
-v バージョン情報を表示する.
var=value 大域変数 var を文字列 "value" に指定する.
filename ファイル filename を実行する.

引数を指定せずに実行した場合,標準入力が端末の時には lua -v -i となり,そうでない場合は lua - となる.

引数は順番に処理される( -c を除く).以下の例では,


       $ lua -i a=test prog.lua

まず標準入力から EOF が入力されるまで対話的に処理を行う.次に a "test" を代入する.最後にファイル prog.lua を 実行する($ はシェルプロンプトでである.あなたのプロンプトは違うかもし れない).

-f filename が指定された場合には,残りのコマンドラインの引数は テーブル arg としてファイル名に対応する Lua プログラムに渡される. テーブル arg は, n が最後の引数のインデクスであり,インデ クス 0 によって "filename" が得られる.以下の例では,


       $ lua a.lua -f b.lua t1 t3

はじめにファイル a.lua が実行される.次に以下のテーブルが作られ る.


       arg = {"t1", "t3";  n = 2, [0] = "b.lua"}

最後に,ファイル b.lua が実行される.

独立した Lua インタプリタは getarg 関数を提供しており, すべ ての コマンドライン引数を参照することができる.以下のように Lua を呼 び出した場合に,


       $ lua -c a b

a または b 中で getargs を実行すると,以下のようなテー ブルが返される.


       {[0] = "lua", [1] = "-c", [2] = "a", [3] = "b", n = 3}

対話モードで複数行に及ぶ文を入力する際,途中の行をバックスラッシュ (`¥') で区切ることができる.大域変数 _PROMPT の値が文字列の場合には, その値がプロンプトとして用いられる.よって,プロンプトは以下のようにコ マンドラインから直接変更できる.


       $ lua _PROMPT='myprompt> ' -i

また, _PROMPT に値を代入する Lua プログラムを実行することによっ ても変更できる.

Unix システムでは,Lua スクリプトは chmod +x コマンドと #! の形式によって実行可能なプログラムになる. 例えば #!/usr/local/bin/lua であり,他の引数を得るには #!/usr/local/bin/lua -f とする.

謝辞

CENPES/PETROBRAS に感謝する.このシステムの初期のバージョンを TeCGraf とともに使っていただき有益なコメントをいただいた. また Carlos Henrique Levy にも感謝する.このゲームの名前をつけていただ いた.Lua は ポルトガル語で「月」を意味する.

以前のバージョンとの非互換性

これまでに配布されたバージョンとの非互換性を除くように注意したが, 互換性が保たれない点がいくつかある.以下にそれを示す.


Lua 3.2 との非互換性


言語仕様の変更


ライブラリの変更


API の変更

Lua の構文一覧