Lua 5.1 リファレンスマニュアル
ロベルト・イエルサリムスキー、ルイス・ヘンリケ・デ・フィゲレド、ワルデマール・セレス 著
Copyright © 2006–2012 Lua.org, PUC-Rio。Luaライセンスの条件の下で自由に利用可能。
1 – 序章
Luaは、一般的な手続き型プログラミングをサポートするために設計された拡張プログラミング言語で、データ記述機能も提供します。また、オブジェクト指向プログラミング、関数型プログラミング、データ駆動型プログラミングにも良いサポートを提供します。Luaは、パワフルで軽量なスクリプト言語として、必要とするすべてのプログラムで使用されることを意図しています。LuaはクリーンなC(つまり、ANSI CとC++の共通部分)で書かれたライブラリとして実装されています。
拡張言語であるLuaには「メイン」プログラムの概念はありません:それはホストクライアントに埋め込まれて動作するのみで、このホストプログラムを埋め込みプログラムまたは単にホストと呼びます。このホストプログラムは、Luaコードの一部を実行するために関数を呼び出すことができ、Lua変数を書き込んだり読み込んだりすることができ、Luaコードによって呼び出されるC関数を登録することができます。C関数の使用を通じて、Luaはさまざまなドメインに対処するために拡張され、構文的フレームワークを共有するカスタマイズされたプログラミング言語を作成することができます。Lua配布には、Luaライブラリを使用して完全なスタンドアロンLuaインタープリタを提供するlua
というサンプルホストプログラムが含まれています。
Luaはフリーソフトウェアであり、ライセンスに記載されている通り、保証はありません。このマニュアルで説明されている実装は、Luaの公式ウェブサイト www.lua.org で入手できます。
他のリファレンスマニュアルと同様に、この文書は場所によっては乾燥しています。Luaの設計背景に関する議論については、Luaのウェブサイトで入手できる技術論文を参照してください。Luaでのプログラミングに関する詳細な紹介については、ロベルトの著書「Programming in Lua(第2版)」を参照してください。
2 – 言語
このセクションでは、Luaの語彙、構文、および意味論について説明します。言い換えれば、このセクションでは、どのトークンが有効であるか、それらをどのように組み合わせることができるか、そしてその組み合わせが何を意味するかを説明します。
言語構造は、通常の拡張BNF記法を使用して説明されます。この記法では、{a}
は0個以上のaを意味し、[a]
はオプションのaを意味します。非終端記号はnon-terminal
のように、キーワードはkword
のように、その他の終端記号は`=´のように示されます。Luaの完全な構文は、このマニュアルの最後にある§8で見ることができます。
2.1 – 字句規則
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
は異なる有効な名前です。慣例として、アンダースコアに続く大文字(例えば_VERSION
)で始まる名前は、Luaによって使用される内部のグローバル変数に予約されています。
次の文字列は他のトークンを示します:
+ - * / % ^ #
== ~= <= >= < > =
( ) { } [ ]
; : , . .. ...
リテラル文字列は、一致する単一または二重引用符で区切ることができ、次のC言語風のエスケープシーケンスを含むことができます:\a
(ベル)、\b
(バックスペース)、\f
(改ページ)、\n
(改行)、\r
(キャリッジリターン)、\t
(水平タブ)、\v
(垂直タブ)、\\
(バックスラッシュ)、\"
(引用符[ダブルクォート])、\'
(アポストロフィ[シングルクォート])。さらに、実際の改行の後にバックスラッシュが続くと、文字列内で改行が発生します。文字列内の文字は、エスケープシーケンス\ddd
を使用して、その数値で指定することもできます。ここでddd
は最大3桁の10進数です。(数値エスケープの後に数字が続く場合、それは正確に3桁を使って表現されなければなりません。)Luaの文字列は、埋め込まれたゼロを含む任意の8ビット値を含むことができ、\0
として指定することができます。
リテラル文字列は、長い括弧で囲まれた長い形式を使用しても定義できます。レベルn
の開始長い括弧を、開始角括弧に続いてn
個の等号が続き、さらに別の開始角括弧が続くと定義します。したがって、レベル0の開始長い括弧は[[
と書かれ、レベル1の開始長い括弧は[=[
と書かれ、以下同様です。閉じ長い括弧も同様に定義されます。たとえば、レベル4の閉じ長い括弧は]====]
と書かれます。長い文字列は、任意のレベルの開始長い括弧で始まり、同じレベルの最初の閉じ長い括弧で終わります。この括弧形式のリテラルは複数行にわたることができ、エスケープシーケンスを解釈せず、他のレベルの長い括弧をすべて無視します。適切なレベルの閉じ括弧を除き、何でも含むことができます。
便宜上、開始長い括弧の直後に改行がある場合、その改行は文字列に含まれません。例えば、ASCIIを使用するシステムでは('a'は97としてコード化され、改行は10として、'1'は49としてコード化されます)、以下の五つのリテラル文字列は同じ文字列を示します:
a = 'alo\n123"'
a = "alo\n123\""
a = '\97lo\10\04923"'
a = [[alo
123"]]
a = [==[
alo
123"]==]
数値定数は、オプションで小数部と小数指数を付けて書くことができます。Luaは整数の16進定数も受け入れ、これには0xを前置します。有効な数値定数の例は以下の通りです。
3 3.0 3.1416 314.16e-2 0.31416E1 0xff 0x56
コメントは、文字列の外部のどこでも二つのハイフン(--
)で始まります。--
の直後のテキストが開始長い括弧でない場合、そのコメントは短いコメントであり、行の終わりまで続きます。そうでなければ、それは長いコメントであり、対応する閉じ長い括弧まで続きます。長いコメントは、コードを一時的に無効にするために頻繁に使用されます。
2.2 – 値と型
Luaは動的型付け言語です。これは、変数に型がなく、値にのみ型があることを意味します。言語には型定義がありません。すべての値は自身の型を持ちます。
Luaのすべての値はファーストクラスの値です。これは、すべての値を変数に格納したり、他の関数への引数として渡したり、結果として返すことができることを意味します。
Luaには8つの基本型があります:nil
、boolean
、number
、string
、function
、userdata
、thread
、そしてtable
です。nil
は値nil
の型であり、他のいかなる値とも異なることが主な特徴で、通常は有用な値の欠如を表します。boolean
は値false
とtrue
の型です。nil
とfalse
の両方が条件を偽にします。それ以外の値は条件を真にします。number
は実数(倍精度浮動小数点)を表します。(単精度浮動小数点数や長整数など、数値のための他の内部表現を使用してLuaインタープリタを構築することは容易です。ファイルluaconf.h
を参照してください。)string
は文字の配列を表します。Luaは8ビットクリーンです:文字列には任意の8ビット文字を含むことができ、組み込まれたゼロ(\0
)を含むこともできます(§2.1を参照)。
Luaは、Luaで書かれた関数とCで書かれた関数を呼び出し(そして操作)することができます(§2.5.8を参照)。
userdata
型は、任意のCデータをLua変数に格納することを可能にするために提供されます。この型は生のメモリブロックに対応し、Luaでは割り当てと同一性テスト以外に定義された操作はありません。しかし、メタテーブルを使用することで、プログラマーはuserdata
値のための操作を定義することができます(§2.8を参照)。userdata
値はLua内で作成または変更することはできず、C APIを通じてのみ可能です。これにより、ホストプログラムによって所有されるデータの完全性が保証されます。
thread
型は独立した実行スレッドを表し、コルーチンの実装に使用されます(§2.11を参照)。オペレーティングシステムのスレッドとLuaのスレッドを混同しないでください。Luaはスレッドをサポートしないシステムでもコルーチンをサポートしています。
table
型は連想配列を実装しており、つまり、配列は数値だけでなく、任意の値(nil
を除く)でインデックス付けすることができます。テーブルは異種混合であり、つまり、nil
を除くすべての型の値を含むことができます。テーブルはLuaの唯一のデータ構造化メカニズムであり、通常の配列、シンボルテーブル、セット、レコード、グラフ、ツリーなどを表現するために使用することができます。レコードを表すために、Luaはフィールド名をインデックスとして使用します。言語は、a["name"]
のための構文糖としてa.name
を提供することにより、この表現をサポートします。Luaでテーブルを作成するためのいくつかの便利な方法があります(§2.5.7を参照)。
インデックスと同様に、テーブルフィールドの値は任意の型(nil
を除く)をとることができます。特に、関数はファーストクラスの値であるため、テーブルフィールドは関数を含むことができます。したがって、テーブルはメソッドも持つことができます(§2.5.9を参照)。
テーブル、関数、スレッド、および(完全な)userdata
値はオブジェクトです:変数は実際にこれらの値を含まず、それらへの参照のみを含みます。代入、パラメータ渡し、および関数の返り値は常にそのような値への参照を操作し、これらの操作はコピーを意味しません。
ライブラリ関数type
は、与えられた値の型を記述する文字列を返します。
2.2.1 – 強制変換
Luaは実行時に文字列と数値の間の自動変換を提供します。文字列に適用された任意の算術演算は、通常の変換ルールに従ってこの文字列を数値に変換しようとします。逆に、文字列が期待される場所で数値が使用されると、数値は適切な形式の文字列に変換されます。数値が文字列に変換される方法を完全に制御するには、文字列ライブラリからformat
関数を使用します(string.format
を参照)。
2.3 – 変数
変数は値を格納する場所です。Luaには三種類の変数があります:グローバル変数、ローカル変数、およびテーブルフィールド。
単一の名前は、グローバル変数、ローカル変数(または関数の形式的なパラメータである、特定の種類のローカル変数)を示すことができます:
var ::= Name
Name
は、§2.1で定義されているように、識別子を示します。
変数は明示的にローカルと宣言されない限り、グローバルと見なされます(§2.4.7を参照)。ローカル変数はレキシカルスコープです:ローカル変数は、そのスコープ内で定義された関数によって自由にアクセスできます(§2.6を参照)。
変数への最初の代入の前に、その値はnil
です。
テーブルのインデックスには角括弧が使用されます:
var ::= prefixexp `[´ exp `]´
グローバル変数とテーブルフィールドへのアクセスの意味は、メタテーブルを介して変更することができます。インデックス付き変数t[i]
へのアクセスは、gettable_event(t,i)
の呼び出しに相当します。(gettable_event
関数の完全な説明については§2.8を参照してください。この関数はLuaでは定義されておらず、呼び出すこともできません。ここでは説明目的でのみ使用しています。)
構文var.Name
は、var["Name"]
のための単なるシンタックスシュガーです:
var ::= prefixexp `.´ Name
すべてのグローバル変数は、環境テーブルまたは単に環境と呼ばれる通常のLuaテーブルのフィールドとして存在します(§2.9を参照)。各関数は自身の環境への参照を持っているので、この関数内のすべてのグローバル変数はこの環境テーブルを参照します。関数が作成されると、それは作成した関数の環境を継承します。Lua関数の環境テーブルを取得するにはgetfenv
を呼び出します。それを置き換えるにはsetfenv
を呼び出します。(C関数の環境はデバッグライブラリを通じてのみ操作できます;(§5.9を参照)。)
グローバル変数x
へのアクセスは、_env.x
に相当し、これはさらに
gettable_event(_env, "x")
に相当します。ここで_env
は実行中の関数の環境です。(gettable_event
関数の完全な説明については§2.8を参照してください。この関数はLuaでは定義されておらず、呼び出すこともできません。同様に、_env
変数もLuaで定義されていません。ここでは説明目的でのみ使用しています。)
2.4 – ステートメント
Luaは、PascalやCに似たほぼ従来のステートメントセットをサポートしています。このセットには、代入、制御構造、関数呼び出し、変数宣言が含まれます。
2.4.1 – チャンク
Luaの実行単位はチャンクと呼ばれます。チャンクは単に一連のステートメントであり、順番に実行されます。各ステートメントはオプションでセミコロンに続くことができます:
chunk ::= {stat [`;´]}
空のステートメントは存在しないため、';;'は不正です。
Luaはチャンクを引数の数が可変である匿名関数の本体として扱います(§2.5.9を参照)。そのため、チャンクはローカル変数を定義し、引数を受け取り、値を返すことができます。
チャンクは、ホストプログラム内のファイルまたは文字列に格納することができます。チャンクを実行するには、Luaはまずチャンクを仮想マシンの命令にプリコンパイルし、次に仮想マシン用のインタプリタでコンパイルされたコードを実行します。
チャンクはバイナリ形式にプリコンパイルすることもできます。詳細はプログラムluac
を参照してください。ソースとコンパイルされた形式のプログラムは互換性があり、Luaはファイルタイプを自動的に検出し、それに応じて動作します。
2.4.2 – ブロック
ブロックは、ステートメントのリストです。構文的には、ブロックはチャンクと同じです:
block ::= chunk
ブロックは明示的に区切ることで単一のステートメントを生成することができます:
stat ::= do block end
明示的なブロックは、変数宣言のスコープを制御するために役立ちます。明示的なブロックは、別のブロックの途中にreturnやbreakステートメントを追加するためにも時々使用されます(§2.4.4を参照)。
2.4.3 – 代入
Luaは複数の代入を許可します。したがって、代入の構文では、左側に変数のリスト、右側に式のリストが定義されます。両リストの要素はコンマで区切られます:
stat ::= varlist `=´ explist
varlist ::= var {`,´ var}
explist ::= exp {`,´ exp}
式については§2.5で議論されます。
代入の前に、値のリストは変数のリストの長さに調整されます。必要以上の値がある場合、余分な値は捨てられます。必要な値が足りない場合、リストは必要な数のnil
で拡張されます。式のリストが関数呼び出しで終わる場合、その呼び出しによって返されるすべての値が調整の前に値のリストに入ります(呼び出しが括弧で囲まれている場合を除く;§2.5を参照)。
代入文は、最初にすべての式を評価し、その後に代入が行われます。したがって、コード
i = 3
i, a[i] = i+1, 20
はa[3]
を20に設定し、a[i]
のiが4に割り当てられる前に(3として)評価されるため、a[4]
には影響を与えません。同様に、行
x, y = y, x
はxとyの値を交換し、
x, y, z = y, z, x
はx、y、zの値を循環的に置換します。
グローバル変数とテーブルフィールドへの代入の意味は、メタテーブルを介して変更できます。インデックス付き変数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で定義されていません。ここでは説明の目的でのみ使用します。)
2.4.4 – 制御構造
制御構造if
、while
、repeat
は、通常の意味と馴染みのある構文を持っています:
stat ::= while exp do block end
stat ::= repeat block until exp
stat ::= if exp then block {elseif exp then block} [else block] end
Luaには、for
文も二つの形式であります(§2.4.5を参照)。
制御構造の条件式は任意の値を返すことができます。false
とnil
は偽と見なされます。nil
とfalse
以外のすべての値は真と見なされます(特に、数字の0と空の文字列も真です)。
repeat–until
ループでは、内部ブロックはuntil
キーワードで終了するのではなく、条件の後でのみ終了します。したがって、条件はループブロック内で宣言されたローカル変数を参照することができます。
return
文は、関数またはチャンク(実質的には関数です)から値を返すために使用されます。関数とチャンクは複数の値を返すことができるため、return
文の構文は次のようになります:
stat ::= return [explist]
break
文は、while
、repeat
、またはfor
ループの実行を終了し、ループの次の文へスキップするために使用されます:
stat ::= break
break
は最も内側のループを終了させます。
return
文とbreak
文は、ブロックの最後の文としてのみ書くことができます。ブロックの途中でreturn
またはbreak
を実行する必要がある場合は、do return end
やdo break end
の慣用句にあるように、明示的な内部ブロックを使用できます。なぜなら、return
とbreak
はそれぞれの(内部)ブロックで最後の文になるからです。
2.4.5 – For文
for
文には数値形式と汎用形式の2つの形式があります。
数値for
ループは、制御変数が算術進行を通過する間、コードブロックを繰り返します。次の構文を持っています:
stat ::= for Name `=´ exp `,´ exp [`,´ exp] do block end
このブロックは、最初のexp
の値から始まり、第二のexp
を第三のexp
のステップで超えるまで繰り返されます。より正確には、以下のようなfor
文
for v = e1, e2, e3 do block end
は次のコードと等価です:
do
local var, limit, step = tonumber(e1), tonumber(e2), tonumber(e3)
if not (var and limit and step) then error() end
while (step > 0 and var <= limit) or (step <= 0 and var >= limit) do
local v = var
block
var = var + step
end
end
次の点に注意してください:
- 3つの制御式はループ開始前に一度だけ評価されます。すべて数値として評価されなければなりません。
var
、limit
、step
は見えない変数です。ここで示されている名前は説明の目的のみのものです。- 第三の式(ステップ)がない場合は、ステップ1が使用されます。
for
ループを抜けるにはbreak
を使用できます。- ループ変数
v
はループにローカルです。for
が終了するか中断された後、その値を使用することはできません。この値が必要な場合は、ループを抜ける前に別の変数に割り当ててください。
汎用for
文は関数、つまりイテレータ上で動作します。各繰り返しで、イテレータ関数が呼び出されて新しい値を生成し、この新しい値がnil
になったときに停止します。汎用for
ループの構文は次のとおりです:
stat ::= for namelist in explist do block end
namelist ::= Name {`,´ Name}
次のようなfor
文
for var_1, ···, var_n in explist do block end
は次のコードと等価です:
do
local f, s, var = explist
while true do
local var_1, ···, var_n = f(s, var)
var = var_1
if var == nil then break end
block
end
end
次の点に注意してください:
explist
は一度だけ評価されます。その結果はイテレータ関数、状態、および最初のイテレータ変数の初期値です。f
、s
、およびvar
は見えない変数です。名前はここで説明目的のみです。for
ループを抜けるにはbreak
を使用できます。- ループ変数
var_i
はループにローカルです。for
が終了した後、これらの値を使用することはできません。これらの値が必要な場合は、ループを抜ける前に他の変数に割り当ててください。
2.4.6 – 文としての関数呼び出し
副作用があるかもしれないため、関数呼び出しは文として実行できます:
stat ::= functioncall
この場合、すべての返された値は破棄されます。関数呼び出しについては§2.5.8で説明されています。
2.4.7 – ローカル宣言
ローカル変数はブロック内のどこでも宣言できます。宣言には初期代入を含めることができます:
stat ::= local namelist [`=´ explist]
初期代入がある場合、そのセマンティクスは複数代入と同じです(§2.4.3を参照)。そうでない場合、すべての変数はnil
で初期化されます。
チャンクもブロックです(§2.4.1を参照)、したがってローカル変数は明示的なブロックの外のチャンクで宣言できます。そのようなローカル変数のスコープはチャンクの終わりまで広がります。
ローカル変数の可視性ルールについては§2.6で説明されています。
2.5 – 式
Luaの基本的な式は以下の通りです:
exp ::= prefixexp
exp ::= nil | false | true
exp ::= Number
exp ::= String
exp ::= function
exp ::= tableconstructor
exp ::= '...'
exp ::= exp binop exp
exp ::= unop exp
prefixexp ::= var | functioncall | '(' exp ')'
数値とリテラル文字列については§2.1で、変数については§2.3で、関数定義については§2.5.9で、関数呼び出しについては§2.5.8で、テーブルコンストラクタについては§2.5.7で説明されています。変数引数式(...
で示される)は、変数引数関数の直接内部でのみ使用でき、§2.5.9で説明されています。
二項演算子には算術演算子(§2.5.1参照)、関係演算子(§2.5.2参照)、論理演算子(§2.5.3参照)、および連結演算子(§2.5.4参照)が含まれます。単項演算子には単項マイナス(§2.5.1参照)、単項 not(§2.5.3参照)、および単項長さ演算子(§2.5.5参照)が含まれます。
関数呼び出しと変数引数式の両方は、複数の値を返すことができます。式が文として使用される場合(関数呼び出しにのみ可能で、§2.4.6を参照)、その戻り値リストはゼロ要素に調整され、すべての返された値が破棄されます。式が式のリストの最後(または唯一の)要素として使用される場合、調整は行われません(呼び出しが括弧で囲まれている場合を除く)。その他のすべてのコンテキストでは、Luaは結果リストを1つの要素に調整し、最初の1つを除いてすべての値を破棄します。
以下に例を示します:
f() -- 0の結果に調整されます
g(f(), x) -- `f()`は1の結果に調整されます
g(x, f()) -- `g`は`x`と`f()`からのすべての結果を受け取ります
a, b, c = f(), x -- `f()`は1の結果に調整されます(`c`は`nil`を受け取ります)
a, b = ... -- `a`は最初の変数引数パラメータを、`b`は2番目を受け取ります(対応する変数引数パラメータがない場合、`a`と`b`は`nil`を受け取る可能性があります)
a, b, c = x, f() -- `f()`は2の結果に調整されます
a, b, c = f() -- `f()`は3の結果に調整されます
return f() -- `f()`からのすべての結果を返します
return ... -- 受け取ったすべての変数引数パラメータを返します
return x, y, f() -- `x`, `y`および`f()`からのすべての結果を返します
{f()} -- `f()`からのすべての結果を含むリストを作成します
{...} -- すべての変数引数パラメータを含むリストを作成します
{f(), nil} -- `f()`は1の結果に調整されます
括弧で囲まれた式は常に1つの値のみを結果として得ます。したがって、(f(x, y, z))
はf
が複数の値を返す場合でも常に単一の値になります。((f(x, y, z))
の値はf
が返す最初の値、またはf
が値を返さない場合はnil
になります。)
2.5.1 – 算術演算子
Luaは通常の算術演算子をサポートしています: 二項+
(加算)、-
(減算)、*
(乗算)、/
(除算)、%
(剰余)、^
(累乗); および単項-
(否定)。オペランドが数値、または数値に変換可能な文字列の場合(§2.2.1を参照)、すべての操作は通常の意味を持ちます。累乗は任意の指数に対して機能します。例えば、x^(-0.5)
はx
の平方根の逆数を計算します。剰余は以下のように定義されます:
a % b == a - math.floor(a/b) * b
つまり、商をマイナス無限大に丸めた除算の剰余です。
2.5.2 – 関係演算子
Luaの関係演算子は以下の通りです:
==
~=
<
>
<=
>=
これらの演算子の結果は常にfalse
またはtrue
です。
等価演算子(==
)はまずオペランドの型を比較します。型が異なる場合、結果はfalse
になります。そうでなければ、オペランドの値が比較されます。数値と文字列は通常の方法で比較されます。オブジェクト(テーブル、ユーザデータ、スレッド、関数)は参照によって比較されます:2つのオブジェクトが同じオブジェクトである場合にのみ等しいと見なされます。新しいオブジェクト(テーブル、ユーザデータ、スレッド、または関数)を作成するたびに、この新しいオブジェクトは以前に存在した任意のオブジェクトと異なります。
Luaでテーブルやユーザデータの比較方法を変更するには、"eq"メタメソッドを使用できます(§2.8を参照)。
等価性比較には§2.2.1の変換規則は適用されません。したがって、"0"==0
はfalse
と評価され、t[0]
とt["0"]
はテーブル内の異なるエントリを示します。
~=
演算子は等価(==
)の正確な否定です。
順序演算子は次のように機能します。両方の引数が数値の場合、そのように比較されます。さもなければ、両方の引数が文字列の場合、現在のロケールに従って値が比較されます。さもなければ、Luaは"lt"または"le"メタメソッドを呼び出そうとします(§2.8を参照)。比較a > b
はb < a
に、a >= b
はb <= a
に変換されます。
2.5.3 – 論理演算子
Luaの論理演算子はand
、or
、not
です。制御構造(§2.4.4を参照)と同様に、すべての論理演算子はfalse
とnil
をfalse
とみなし、それ以外のものをtrue
とみなします。
否定演算子not
は常にfalse
またはtrue
を返します。論理積演算子and
は、その第一引数がfalse
またはnil
の場合にその値を返し、それ以外の場合は第二引数を返します。論理和演算子or
は、その第一引数がnil
とfalse
以外の場合にその値を返し、それ以外の場合は第二引数を返します。and
とor
はどちらもショートカット評価を使用します。つまり、第二オペランドは必要に応じてのみ評価されます。ここにいくつかの例を示します:
10 or 20 --> `10`
10 or error() --> `10`
nil or "a" --> `"a"`
nil and 10 --> `nil`
false and error() --> `false`
false and nil --> `false`
false or nil --> `nil`
10 and 20 --> `20`
(このマニュアルでは、-->
は前の式の結果を示します。)
2.5.4 – 連結
Luaでの文字列連結演算子は二つのドット(..
)で表されます。両オペランドが文字列または数値の場合、§2.2.1に記載されている規則に従って文字列に変換されます。それ以外の場合は、"concat"メタメソッドが呼び出されます(§2.8を参照)。
2.5.5 – 長さ演算子
長さ演算子は単項演算子#
で表されます。文字列の長さはそのバイト数です(つまり、各文字が1バイトの場合の通常の文字列の長さの意味です)。
テーブルt
の長さは、t[n]
がnil
でなく、t[n+1]
がnil
であるような任意の整数インデックスn
と定義されます。さらに、t[1]
がnil
の場合、n
はゼロになることがあります。通常の配列では、1からあるn
までの非nil
値がある場合、その長さは正確にそのn
、すなわち最後の値のインデックスです。配列に「穴」(つまり、他の非nil
値の間にnil
値がある場合)がある場合、#t
はnil
値の直前の任意のインデックスになる可能性があります(つまり、配列の終わりとしてそのようなnil
値を考慮することがあります)。
2.5.6 – 優先順位
Luaにおける演算子の優先順位は、以下の表に従い、低いものから高いものへとなります:
or
and
<
>
<=
>=
~=
==
..
+
-
*
/
%
not
#
-
(単項)^
通常、括弧を使用して式の優先順位を変更できます。連結(..
)と累乗(^
)演算子は右結合です。他のすべての二項演算子は左結合です。
2.5.7 – テーブルコンストラクタ
テーブルコンストラクタは、テーブルを生成する式です。コンストラクタが評価されるたびに新しいテーブルが作成されます。コンストラクタは、空のテーブルを作成するか、またはテーブルを作成してそのいくつかのフィールドを初期化するために使用できます。コンストラクタの一般的な構文は以下の通りです:
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 t = {}
t[f(1)] = g
t[1] = "x" -- 1st exp
t[2] = "y" -- 2nd exp
t.x = 1 -- t["x"] = 1
t[3] = f(x) -- 3rd exp
t[30] = 23
t[4] = 45 -- 4th exp
a = t
end
リストの最後のフィールドがexp
の形をしており、式が関数呼び出しまたは変数引数式である場合、この式によって返されたすべての値が連続してリストに入ります(§2.5.8を参照)。これを避けるには、関数呼び出しまたは変数引数式を括弧で囲みます(§2.5を参照)。
フィールドリストは、機械生成コードの便宜のために、オプションの末尾区切り文字を持つことができます。
2.5.8 – 関数呼び出し
Luaでの関数呼び出しは次の構文を持ちます:
functioncall ::= prefixexp args
関数呼び出しでは、最初にprefixexp
とargs
が評価されます。prefixexp
の値の型が関数であれば、指定された引数でこの関数が呼び出されます。そうでなければ、prefixexp
の"call"メタメソッドが呼び出され、最初のパラメーターとしてprefixexp
の値が渡され、その後に元の呼び出し引数が続きます(§2.8を参照)。
以下の形式
functioncall ::= prefixexp ':' Name args
は"メソッド"の呼び出しに使用できます。呼び出しv:name(args)
はv.name(v,args)
の糖衣構文ですが、v
は一度だけ評価されます。
引数は次の構文を持ちます:
args ::= '(' [explist] ')'
args ::= tableconstructor
args ::= String
すべての引数表現は呼び出し前に評価されます。形式f{fields}
の呼び出しはf({fields})
の糖衣構文です。つまり、引数リストは単一の新しいテーブルです。形式f'string'
(またはf"string"
やf[[string]]
)の呼び出しはf('string')
の糖衣構文です。つまり、引数リストは単一のリテラル文字列です。
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つの結果に調整されます
2.5.9 – 関数定義
関数定義の構文は以下の通りです:
function ::= function funcbody
funcbody ::= '(' [parlist] ')' block end
関数定義を簡略化するための糖衣構文は次のとおりです:
stat ::= function funcname funcbody
stat ::= local function Name funcbody
funcname ::= Name {'.' Name} [':' Name]
次のステートメント
function f () body end
は以下に変換されます:
f = function () body end
次のステートメント
function t.a.b.c.f () body end
は以下に変換されます:
t.a.b.c.f = function () body end
次のステートメント
local function f () body end
は以下に変換されます:
local f; f = function () body end
以下のようには変換されません:
local f = function () body end
(これは関数の本体がf
を参照している場合にのみ差が出ます。)
関数定義は実行可能な式であり、その値の型はfunction
です。Luaがチャンクをプリコンパイルすると、そのすべての関数本体もプリコンパイルされます。そして、Luaが関数定義を実行するたびに、関数はインスタンス化(またはクローズ)されます。この関数インスタンス(またはクロージャ)は式の最終値です。同じ関数の異なるインスタンスは、異なる外部ローカル変数を参照したり、異なる環境テーブルを持つことができます。
パラメータは引数の値で初期化されるローカル変数として機能します:
parlist ::= namelist [',' '...'] | '...'
関数が呼び出されると、引数のリストはパラメータリストの長さに調整されます。ただし、関数が可変長またはvararg関数の場合はこの限りではありません。これは、パラメータリストの末尾に3つのドット(...
)によって示されます。vararg関数は引数リストを調整しません。代わりに、すべての追加引数を収集し、これらを関数にvararg式を通じて提供します。この式も3つのドットで書かれます。この式の値は、複数の結果を持つ関数のように、すべての実際の追加引数のリストです。vararg式が別の式内や式のリストの途中で使用される場合、その戻りリストは1つの要素に調整されます。式が式のリストの最後の要素として使用される場合、調整は行われません(最後の式が括弧で囲まれている場合を除く)。
例として、次の定義を考えてみましょう:
function f(a, b) end
function g(a, b, ...) end
function r() return 1,2,3 end
次に、引数からパラメータおよびvararg式へのマッピングを示します:
呼び出し | パラメータ |
---|---|
f(3) | a=3, b=nil |
f(3, 4) | a=3, b=4 |
f(3, 4, 5) | a=3, b=4 |
f(r(), 10) | a=1, b=10 |
f(r()) | a=1, b=2 |
g(3) | a=3, b=nil, ... --> (なし) |
g(3, 4) | a=3, b=4, ... --> (なし) |
g(3, 4, 5, 8) | a=3, b=4, ... --> 5 8 |
g(5, r()) | a=5, b=1, ... --> 2 3 |
結果はreturn
文を使用して返されます(§2.4.4を参照)。関数の最後に到達してreturn
文に遭遇しない場合、その関数は結果なしで返されます。
コロン構文は、暗黙の追加パラメータself
を持つ関数、つまりメソッドを定義するために使用されます。したがって、文
function t.a.b.c:f (params) body end
は、以下のためのシンタックスシュガーです:
t.a.b.c.f = function (self, params) body end
2.6 – 可視性ルール
Luaはレキシカルスコープ言語です。変数のスコープは宣言後の最初の文から始まり、宣言を含む最も内側のブロックの終わりまで続きます。以下の例を考えてみましょう:
x = 10 -- グローバル変数
do -- 新しいブロック
local x = x -- 新しい'x'、値は10
print(x) --> 10
x = x+1
do -- 別のブロック
local x = x+1 -- 別の'x'
print(x) --> 12
end
print(x) --> 11
end
print(x) --> 10 (グローバルな方)
local x = x
のような宣言では、宣言されている新しいxはまだスコープ内になく、したがって2つ目のxは外側の変数を指します。
レキシカルスコープのルールのため、ローカル変数はそのスコープ内で定義された関数によって自由にアクセスできます。内部関数によって使用されるローカル変数は、内部関数内でアップバリューまたは外部ローカル変数と呼ばれます。
ローカル文の各実行が新しいローカル変数を定義することに注意してください。次の例を考えてみましょう:
a = {}
local x = 20
for i=1,10 do
local y = 0
a[i] = function () y=y+1; return x+y end
end
このループは10個のクロージャ(つまり、無名関数の10インスタンス)を作成します。これらのクロージャはそれぞれ異なるy
変数を使用する一方で、すべてのクロージャが同じx
を共有します。
2.7 – エラー処理
Luaは組み込み拡張言語であるため、すべてのLuaアクションはホストプログラムのCコードからLuaライブラリの関数を呼び出すことで開始されます(lua_pcall
を参照)。Luaのコンパイルまたは実行中にエラーが発生すると、制御はCに戻り、適切な対策(エラーメッセージの表示など)を取ることができます。
Luaコードは、error
関数を呼び出して明示的にエラーを生成できます。Lua内でエラーをキャッチする必要がある場合は、pcall
関数を使用できます。
2.8 – メタテーブル
Luaのすべての値はメタテーブルを持つことができます。このメタテーブルは通常のLuaテーブルであり、特定の特殊な操作の下で元の値の振る舞いを定義します。メタテーブル内の特定のフィールドを設定することで、値に対する操作の振る舞いのいくつかの側面を変更できます。たとえば、加算のオペランドが数値でない値の場合、Luaはそのメタテーブル内の"__add"
フィールドに関数があるかどうかを確認します。見つかった場合、Luaはこの関数を呼び出して加算を実行します。
メタテーブル内のキーをイベントと呼び、値をメタメソッドと呼びます。前の例では、イベントは"add"であり、メタメソッドは加算を実行する関数です。
getmetatable
関数を通じて任意の値のメタテーブルを問い合わせることができます。
setmetatable
関数を通じてテーブルのメタテーブルを置き換えることができます。Luaから他の型のメタテーブルを変更することはできません(デバッグライブラリを使用する場合を除く);それにはC APIを使用する必要があります。
テーブルと完全なuserdata
は個別のメタテーブルを持ちます(ただし、複数のテーブルとuserdata
がそのメタテーブルを共有することは可能です)。他のすべての型の値は、タイプごとに1つの単一のメタテーブルを共有します。つまり、すべての数値に1つのメタテーブル、すべての文字列に1つのメタテーブルなどがあります。
メタテーブルは、算術演算、順序比較、連結、長さ操作、およびインデックス付けにおいてオブジェクトの振る舞いを制御します。メタテーブルは、userdata
がガーベジコレクトされたときに呼び出される関数を定義することもできます。これらの操作ごとに、Luaはイベントと呼ばれる特定のキーを関連付けます。Luaが値に対してこれらの操作のいずれかを実行するとき、対応するイベントを持つメタテーブルがその値にあるかどうかをチェックします。もしある場合、そのキー(メタメソッド)に関連付けられた値が、Luaが操作をどのように実行するかを制御します。
メタテーブルは次に示す操作を制御します。各操作はそれに対応する名前で識別されます。各操作のキーは、2つのアンダースコア'__'
でプレフィックスされたその名前の文字列です。例えば、"add"操作のキーは文字列"__add"
です。これらの操作のセマンティクスは、インタプリタが操作をどのように実行するかを説明するLua関数によってよりよく説明されます。
ここに示されたLuaのコードは説明用です。実際の振る舞いはインタプリタにハードコードされており、このシミュレーションよりもはるかに効率的です。これらの説明で使用されるすべての関数(rawget
、tonumber
など)は§5.1で説明されています。特に、与えられたオブジェクトのメタメソッドを取得するには、次の式を使用します
metatable(obj)[event]
これは以下のように読むべきです
rawget(getmetatable(obj) or {}, event)
つまり、メタメソッドへのアクセスは他のメタメソッドを呼び出さず、メタテーブルを持たないオブジェクトへのアクセスが失敗することはありません(単にnil
を返します)。
- "add":+ 操作です。
以下のgetbinhandler
関数は、Luaが二項演算のハンドラーをどのように選択するかを定義しています。まず、Luaは最初のオペランドを試します。その型が操作のハンドラーを定義していない場合、Luaは2番目のオペランドを試します。
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 -- ここでの'+'はプリミティブな'add'
else -- 少なくとも1つのオペランドが数値ではありません
local h = getbinhandler(op1, op2, "__add")
if h then
-- 両オペランドでハンドラを呼び出す
return (h(op1, op2))
else -- 利用可能なハンドラがありません:デフォルトの振る舞い
error(···)
end
end
end
- "sub":- 演算。"add"演算と同様の振る舞い。
- "mul":* 演算。"add"演算と同様の振る舞い。
- "div":/ 演算。"add"演算と同様の振る舞い。
- "mod":%演算。"add"演算と同様の振る舞いですが、プリミティブな操作は
o1 - floor(o1/o2)*o2
です。 - "pow":^(べき乗)演算。"add"演算と同様の振る舞いで、プリミティブな操作はCの数学ライブラリの
pow
関数です。 - "unm":単項- 演算。
function unm_event (op)
local o = tonumber(op)
if o then -- オペランドは数値ですか?
return -o -- ここでの'-'はプリミティブな'unm'
else -- オペランドが数値ではありません。
-- オペランドからハンドラを取得しようとする
local h = metatable(op).__unm
if h then
-- オペランドでハンドラを呼び出す
return (h(op))
else -- 利用可能なハンドラがありません:デフォルトの振る舞い
error(···)
end
end
end
- "concat":
..
(連結)操作です。
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
- "len":
#
操作です。
function len_event (op)
if type(op) == "string" then
return strlen(op) -- 原始的な文字列長
elseif type(op) == "table" then
return #op -- 原始的なテーブル長
else
local h = metatable(op).__len
if h then
-- オペランドでハンドラを呼び出す
return (h(op))
else -- 利用可能なハンドラがない:デフォルトの動作
error(···)
end
end
end
テーブルの長さについては§2.5.5を参照してください。
- "eq":
==
操作です。関数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)
と等価です。
- "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 h = getcomphandler(op1, op2, "__lt")
if h then
return (h(op1, op2))
else
error(···)
end
end
end
a > b
はb < a
と等価です。
- "le":
<=
操作。
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は"lt"
を試み、a <= b
がnot (b < a)
と等価であると仮定します。
- "index": インデクシングアクセス
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
end
- "newindex": インデクシング代入
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
h(table, key, value) -- ハンドラを呼び出す
else h[key] = value -- またはそれに対して操作を繰り返す
end
end
- "call": Luaが値を呼び出すときに呼び出される。
function function_event (func, ...)
if type(func) == "function" then
return func(...) -- 基本的な呼び出し
else
local h = metatable(func).__call
if h then
return h(func, ...)
else
error(···)
end
end
end
2.9 – 環境
メタテーブルの他に、スレッド、関数、およびuserdata
の型のオブジェクトには、それらの環境と呼ばれる別のテーブルが関連付けられています。メタテーブルと同様に、環境は通常のテーブルであり、複数のオブジェクトが同じ環境を共有できます。
スレッドは作成スレッドの環境を共有して作成されます。userdata
とC関数は、それを作成するC関数の環境を共有して作成されます。ネストされていないLua関数(loadfile
、loadstring
、またはload
によって作成されたもの)は、それを作成するスレッドの環境を共有して作成されます。ネストされたLua関数は、それを作成するLua関数の環境を共有して作成されます。
userdata
に関連付けられた環境はLuaにとって意味がありません。これは、プログラマーがuserdata
にテーブルを関連付けるための便利な機能に過ぎません。
スレッドに関連付けられた環境はグローバル環境と呼ばれます。これらはスレッドとネストされていないLua関数のデフォルトの環境として使用され、Cコードから直接アクセスできます(§3.3を参照)。
C関数に関連付けられた環境は、Cコードによって直接アクセスできます(§3.3を参照)。それは他のC関数とuserdata
がその関数によって作成された際のデフォルト環境として使用されます。
Lua関数に関連付けられた環境は、関数内のすべてのグローバル変数へのアクセスを解決するために使用されます(§2.3を参照)。これらは、その関数によって作成されたネストされたLua関数のデフォルト環境として使用されます。
Lua関数または実行中のスレッドの環境を変更するにはsetfenv
を呼び出します。Lua関数または実行中のスレッドの環境を取得するにはgetfenv
を呼び出します。他のオブジェクト(userdata
、C関数、他のスレッド)の環境を操作するには、C APIを使用する必要があります。
2.10 – ガーベジコレクション
Luaは自動メモリ管理を行います。これは、新しいオブジェクトのメモリを確保することや、オブジェクトが不要になったときにそれを解放することについて心配する必要がないことを意味します。Luaは時々ガーベジコレクタを実行して、Luaからアクセスできなくなったすべてのデッドオブジェクト(つまり、もはやアクセスできないオブジェクト)を収集することによって、自動的にメモリを管理します。Luaによって使用されるすべてのメモリは、自動管理の対象です:テーブル、userdata
、関数、スレッド、文字列など。
Luaはインクリメンタルなマーク・アンド・スイープコレクタを実装しています。それはガーベジコレクションサイクルを制御するために2つの数値、ガーベジコレクタのポーズとガーベジコレクタのステップ乗数を使用します。両方ともパーセンテージポイントを単位として使用します(100の値は内部値が1であることを意味します)。
ガーベジコレクタのポーズは、コレクタが新しいサイクルを開始する前に待つ時間を制御します。値が大きいほど、コレクタは積極性が少なくなります。100未満の値は、コレクタが新しいサイクルを開始するのを待たないことを意味します。200の値は、コレクタが新しいサイクルを開始する前に使用中の総メモリが2倍になるのを待つことを意味します。
ステップ乗数は、メモリ割り当てに対するコレクタの相対速度を制御します。値が大きいほど、コレクタは積極的になりますが、各インクリメンタルステップのサイズも増加します。100未満の値はコレクタを遅くしすぎ、コレクタがサイクルを終了しない結果になることがあります。デフォルトの200は、コレクタがメモリ割り当ての「2倍」の速度で実行されることを意味します。
これらの数値は、Cでlua_gc
を呼び出すか、Luaでcollectgarbage
を呼び出すことで変更できます。これらの関数を使用して、コレクタを直接制御することもできます(例:停止および再開)。
2.10.1 – ガーベジコレクションメタメソッド
C APIを使用して、userdata
のガーベジコレクタメタメソッドを設定できます(§2.8を参照)。これらのメタメソッドはファイナライザとも呼ばれます。ファイナライザを使用すると、Luaのガーベジコレクションを外部リソース管理(ファイルのクローズ、ネットワークやデータベース接続の切断、自身のメモリの解放など)と連携させることができます。
メタテーブルに__gc
フィールドを持つガーベジuserdata
は、ガーベジコレクタによってすぐには収集されません。代わりに、Luaはそれらをリストに入れます。収集後、Luaは以下の関数と同等の処理をそのリスト内の各userdata
に対して行います:
function gc_event (udata)
local h = metatable(udata).__gc
if h then
h(udata)
end
end
各ガーベジコレクションサイクルの終わりに、そのサイクルで収集されたものの中で、userdata
のファイナライザは作成された順序と逆の順序で呼び出されます。つまり、最初に呼び出されるファイナライザは、プログラム内で最後に作成されたuserdata
に関連付けられているものです。userdata
自体は、次のガーベジコレクションサイクルでのみ解放されます。
2.10.2 – 弱参照テーブル
弱参照テーブルは、その要素が弱参照であるテーブルです。弱参照はガーベジコレクタによって無視されます。つまり、オブジェクトへの参照が弱参照のみである場合、ガーベジコレクタはそのオブジェクトを収集します。
弱参照テーブルは、弱キー、弱値、またはその両方を持つことができます。弱キーを持つテーブルは、そのキーの収集を許可しますが、その値の収集を防ぎます。弱キーと弱値の両方を持つテーブルは、キーと値の両方の収集を許可します。いずれの場合も、キーまたは値のいずれかが収集されると、そのペア全体がテーブルから削除されます。テーブルの弱さは、そのメタテーブルの__mode
フィールドによって制御されます。__mode
フィールドが文字'k'を含む文字列の場合、テーブル内のキーは弱いです。__mode
に'v'が含まれている場合、テーブル内の値は弱いです。
テーブルをメタテーブルとして使用した後は、その__mode
フィールドの値を変更しないでください。さもないと、このメタテーブルによって制御されるテーブルの弱い振る舞いは未定義となります。
2.11 – コルーチン
Luaはコルーチンをサポートしています。これは協調的マルチスレッドとも呼ばれます。Luaのコルーチンは、実行の独立したスレッドを表します。しかし、マルチスレッドシステムのスレッドとは異なり、コルーチンは明示的にyield
関数を呼び出して実行を一時停止します。
コルーチンはcoroutine.create
の呼び出しで作成されます。その唯一の引数は、コルーチンのメイン関数です。create
関数は新しいコルーチンを作成し、それに対するハンドル(スレッド型のオブジェクト)を返しますが、コルーチンの実行を開始しません。
最初にcoroutine.resume
を呼び出し、coroutine.create
によって返されたスレッドを最初の引数として渡すと、コルーチンはそのメイン関数の最初の行から実行を開始します。coroutine.resume
に渡された追加の引数は、コルーチンのメイン関数に渡されます。コルーチンが実行を開始すると、終了するか、yield
するまで実行が続きます。
コルーチンは、2つの方法で実行を終了することができます:通常は、メイン関数が返されるとき(明示的または暗示的に、最後の命令後)、そして非正常に、保護されていないエラーがある場合です。最初の場合、coroutine.resume
はtrueと、コルーチンのメイン関数によって返された任意の値を返します。エラーの場合、coroutine.resume
はfalseとエラーメッセージを返します。
コルーチンはcoroutine.yield
を呼び出すことによって譲渡(yield)します。コルーチンが譲渡すると、対応するcoroutine.resume
は即座に戻ります。これは、譲渡がネストされた関数呼び出し内で行われても(つまり、メイン関数ではなく、メイン関数によって直接または間接的に呼び出された関数内で行われても)です。譲渡の場合、coroutine.resume
はtrueと、coroutine.yield
に渡された任意の値を返します。次に同じコルーチンを再開するとき、それは譲渡した点から実行を続けます。coroutine.yield
の呼び出しは、coroutine.resume
に渡された追加の引数を返します。
coroutine.create
と同様に、coroutine.wrap
関数もコルーチンを作成しますが、コルーチン自体を返す代わりに、呼び出されたときにコルーチンを再開する関数を返します。この関数に渡された任意の引数は、coroutine.resume
への追加の引数として扱われます。coroutine.wrap
は、coroutine.resume
によって返されるすべての値を返しますが、最初の1つ(ブール型のエラーコード)を除きます。coroutine.resume
とは異なり、coroutine.wrap
はエラーをキャッチしません。任意のエラーは呼び出し元に伝播されます。
例として、以下のコードを考えてください:
function foo (a)
print("foo", a)
return coroutine.yield(2*a)
end
co = coroutine.create(function (a,b)
print("co-body", a, b)
local r = foo(a+1)
print("co-body", r)
local r, s = coroutine.yield(a+b, a-b)
print("co-body", r, s)
return b, "end"
end)
print("main", coroutine.resume(co, 1, 10))
print("main", coroutine.resume(co, "r"))
print("main", coroutine.resume(co, "x", "y"))
print("main", coroutine.resume(co, "x", "y"))
実行すると、次の出力が得られます:
co-body 1 10
foo 2
main true 4
co-body r
main true 11 -9
co-body x y
main true 10 end
main false cannot resume dead coroutine
3 – アプリケーションプログラムインターフェース
このセクションでは、LuaのC API、つまり、ホストプログラムがLuaと通信するために使用できるC関数のセットについて説明します。すべてのAPI関数、関連する型、定数はヘッダファイルlua.h
に宣言されています。
「関数」という用語を使用しても、APIの機能はマクロとして提供されることがあります。そのようなすべてのマクロは、それぞれの引数を一度だけ使用します(最初の引数は常にLuaステートであり、それは除外)し、隠れた副作用を生成しません。
ほとんどのCライブラリと同様に、Lua API関数は引数の有効性や一貫性をチェックしません。ただし、luaconf.h
ファイルでマクロluai_apicheck
の適切な定義を使用してLuaをコンパイルすることによって、この振る舞いを変更することができます。
3.1 – スタック
LuaはCとの間で値を渡すために仮想スタックを使用します。このスタックの各要素はLuaの値(nil、数値、文字列など)を表します。
いつでもLuaがCを呼び出すと、呼び出された関数は新しいスタックを取得します。このスタックは以前のスタックやまだアクティブなC関数のスタックとは独立しています。このスタックには初めにC関数への引数が含まれ、C関数がその結果を呼び出し元に返すためにプッシュする場所です(lua_CFunction
を参照)。
便宜上、APIのほとんどのクエリ操作は厳格なスタック規則に従いません。代わりに、インデックスを使用してスタック内の任意の要素を参照できます。正のインデックスは絶対スタック位置(1から始まる)を表し、負のインデックスはスタックの先頭からの相対的なオフセットを表します。具体的には、スタックにn個の要素がある場合、インデックス1は最初の要素(つまり、スタックに最初にプッシュされた要素)を表し、インデックスnは最後の要素を表します。インデックス-1も最後の要素(つまり、最上部の要素)を表し、インデックス-nは最初の要素を表します。インデックスが有効であるとは、1とスタックの先頭の間にある場合(つまり、1 ≤ abs(index) ≤ top)を指します。
3.2 – スタックサイズ
Lua APIと対話するときは、整合性を保つ責任があります。特に、スタックオーバーフローを制御する責任があります。スタックサイズを増やすには、関数lua_checkstack
を使用できます。
LuaがCを呼び出すとき、少なくともLUA_MINSTACK
のスタック位置が利用可能であることを保証します。LUA_MINSTACK
は20と定義されているため、通常はスタックに要素をプッシュするループがある場合を除き、スタックスペースについて心配する必要はありません。
ほとんどのクエリ関数は、使用可能なスタックスペース内の任意の値をインデックスとして受け入れます。つまり、lua_checkstack
を通じて設定した最大スタックサイズまでのインデックスです。このようなインデックスは許容インデックスと呼ばれます。より形式的に、許容インデックスを次のように定義します:
(index < 0 && abs(index) <= top) ||
(index > 0 && index <= stackspace)
0が許容インデックスであることは決してありません。
3.3 – 擬似インデックス
特に断りがない限り、有効なインデックスを受け入れる任意の関数は、スタック内にはないがCコードからアクセス可能なLuaの値を表す擬似インデックスで呼び出すこともできます。擬似インデックスは、スレッド環境、関数環境、レジストリ、およびC関数のアップバリューにアクセスするために使用されます(§3.4を参照)。
スレッド環境(グローバル変数が存在する場所)は常に擬似インデックスLUA_GLOBALSINDEX
にあります。実行中のC関数の環境は常に擬似インデックスLUA_ENVIRONINDEX
にあります。
グローバル変数の値にアクセスして変更するには、環境テーブルに対する通常のテーブル操作を使用できます。例えば、グローバル変数の値にアクセスするには、次の操作を行います:
lua_getfield(L, LUA_GLOBALSINDEX, varname);
3.4 – Cクロージャ
C関数が作成されるとき、いくつかの値をそれに関連付けてCクロージャを作成することができます。これらの値はアップバリューと呼ばれ、呼び出されるたびに関数からアクセス可能です(lua_pushcclosure
を参照)。
C関数が呼び出されると、そのアップバリューは特定の擬似インデックスに位置します。これらの擬似インデックスはマクロlua_upvalueindex
によって生成されます。関数に関連付けられた最初の値は位置lua_upvalueindex(1)
にあり、以下同様です。lua_upvalueindex(n)
へのアクセスは、nが現在の関数のアップバリューの数より大きい場合(ただし256よりは大きくない場合)、許容される(しかし無効な)インデックスを生成します。
3.5 – レジストリ
Luaはレジストリを提供しており、これはCコードが必要とする任意のLua値を格納するために使用できる事前定義されたテーブルです。このテーブルは常に擬似インデックスLUA_REGISTRYINDEX
に位置しています。任意のCライブラリはこのテーブルにデータを格納できますが、他のライブラリが使用しているキーとの衝突を避けるために、異なるキーを選ぶべきです。通常、キーとしてはライブラリ名を含む文字列やコード内のCオブジェクトのアドレスを持つ軽量ユーザーデータを使用すべきです。
レジストリの整数キーは補助ライブラリによって実装された参照メカニズムに使用されるため、他の目的には使用すべきではありません。
3.6 – Cにおけるエラー処理
内部的に、Luaはエラーを処理するためにCのlongjmp
機能を使用します。(C++を使用している場合は例外を使用することも選択できます。luaconf.h
ファイルを参照してください。)Luaが任意のエラー(メモリ割り当てエラー、型エラー、構文エラー、実行時エラーなど)に遭遇すると、エラーを発生させます。つまり、ロングジャンプを行います。保護された環境はsetjmp
を使用して回復ポイントを設定し、任意のエラーは最も最近のアクティブな回復ポイントにジャンプします。
APIのほとんどの関数は、メモリ割り当てエラーなどのためにエラーを投げる可能性があります。各関数のドキュメントには、それがエラーを投げる可能性があるかどうかが示されています。
C関数内でエラーを投げるには、lua_error
を呼び出します。
3.7 – 関数と型
ここでは、C APIのすべての関数と型をアルファベット順にリストアップします。各関数にはこのような指示があります:[-o, +p, x]
最初のフィールドo
は、関数がスタックからポップする要素の数です。2番目のフィールドp
は、関数がスタックにプッシュする要素の数です。(任意の関数は常に引数をポップした後に結果をプッシュします。)x|y
の形式のフィールドは、関数が状況に応じてx
またはy
要素をプッシュ(またはポップ)できることを意味します。疑問符?
は、その引数だけを見ても関数がポップ/プッシュする要素の数を知ることができないことを意味します(例えば、スタック上のものに依存する場合があります)。3番目のフィールドx
は、関数がエラーを投げるかどうかを示します:-
は関数がエラーを決して投げないことを意味します。m
は、関数がメモリ不足のためにのみエラーを投げる可能性があることを意味します。e
は、関数が他の種類のエラーを投げる可能性があることを意味します。v
は、関数が意図的にエラーを投げる可能性があることを意味します。
lua_Alloc
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
Luaステートによって使用されるメモリ割り当て関数の型です。割り当て関数はrealloc
に似た機能を提供する必要がありますが、全く同じではありません。その引数はud
で、lua_newstate
に渡される不透明なポインタです。ptr
は、割り当て/再割り当て/解放されるブロックへのポインタです。osize
はブロックの元のサイズ、nsize
はブロックの新しいサイズです。ptr
はosize
がゼロの場合、かつその場合に限りNULLです。nsize
がゼロのとき、割り当て関数はNULLを返す必要があります。osize
がゼロでない場合、ptr
を指すブロックを解放する必要があります。nsize
がゼロでないとき、割り当て関数は要求を満たせない場合にのみNULLを返します。nsize
がゼロでなく、osize
がゼロのとき、割り当て関数はmalloc
のように振る舞うべきです。nsize
とosize
がゼロでない場合、割り当て関数はrealloc
のように振る舞います。Luaは、osize
>= nsize
のとき割り当て関数が決して失敗しないと仮定しています。
こちらは割り当て関数のシンプルな実装です。これは補助ライブラリによってluaL_newstate
で使用されます。
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
(void)ud; (void)osize; /* 未使用 */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
このコードはfree(NULL)
が効果を持たないことと、realloc(NULL, size)
がmalloc(size)
に等しいことを前提としています。ANSI Cは両方の振る舞いを保証します。
lua_atpanic
// [-0, +0, -]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);
新しいパニック関数を設定し、古いものを返します。
保護された環境の外でエラーが発生した場合、Luaはパニック関数を呼び出し、その後exit(EXIT_FAILURE)
を呼び出してホストアプリケーションを終了します。パニック関数は(例えば長いジャンプを行うことで)この終了を回避できます。
パニック関数はスタックの先頭にあるエラーメッセージにアクセスできます。
lua_call
// [-(nargs + 1), +nresults, e]
void lua_call (lua_State *L, int nargs, int nresults);
関数を呼び出します。
関数を呼び出すには、次のプロトコルを使用する必要があります:まず、呼び出される関数がスタックにプッシュされます。次に、関数への引数が直接の順番でプッシュされます。つまり、最初の引数が最初にプッシュされます。最後にlua_call
を呼び出します。nargs
はスタックにプッシュした引数の数です。すべての引数と関数の値は、関数が呼び出されるときにスタックからポップされます。関数の結果は、関数が戻るとスタックにプッシュされます。結果の数はnresults
に調整されます。ただし、nresults
がLUA_MULTRET
の場合は、関数からのすべての結果がプッシュされます。Luaは、返された値がスタックスペースに収まるようにします。関数の結果は直接の順序でスタックにプッシュされます(最初の結果が最初にプッシュされる)ので、呼び出しの後に最後の結果がスタックの上にあります。
呼び出された関数内の任意のエラーは上方に伝播されます(longjmpを使用)。
以下の例は、ホストプログラムがこのLuaコードに相当することをどのように行うかを示しています:
a = f("how", t.x, 14)
C言語での実装は次のとおりです:
lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* 呼び出される関数 */
lua_pushstring(L, "how"); /* 1番目の引数 */
lua_getfield(L, LUA_GLOBALSINDEX, "t"); /* インデックスされるテーブル */
lua_getfield(L, -1, "x"); /* t.xの結果をプッシュ(2番目の引数) */
lua_remove(L, -2); /* 't'をスタックから削除 */
lua_pushinteger(L, 14); /* 3番目の引数 */
lua_call(L, 3, 1); /* 'f'を3つの引数と1つの結果で呼び出す */
lua_setfield(L, LUA_GLOBALSINDEX, "a"); /* グローバル'a'を設定 */
上記のコードは「バランスが取れています」:その終わりに、スタックは元の構成に戻ります。これは良いプログラミング習慣とされています。
lua_CFunction
typedef int (*lua_CFunction) (lua_State *L);
C関数のための型です。
Luaと適切に通信するために、C関数は以下のプロトコルを使用する必要があります。これはパラメータと結果の受け渡し方法を定義しています:C関数は引数をLuaからそのスタック内の直接順序で受け取ります(最初の引数が最初にプッシュされます)。したがって、関数が開始するとき、lua_gettop(L)
は関数によって受け取られた引数の数を返します。最初の引数(存在する場合)はインデックス1にあり、最後の引数はインデックスlua_gettop(L)
にあります。Luaに値を返すために、C関数はそれらをスタックに直接順序でプッシュし(最初の結果が最初にプッシュされ)、結果の数を返します。結果の下にあるスタック内の他の値は、Luaによって適切に破棄されます。Lua関数と同様に、Luaによって呼び出されたC関数も多くの結果を返すことができます。
例として、次の関数は可変数の数値引数を受け取り、その平均値と合計値を返します:
static int foo (lua_State *L) {
int n = lua_gettop(L); /* 引数の数 */
lua_Number sum = 0;
int i;
for (i = 1; i <= n; i++) {
if (!lua_isnumber(L, i)) {
lua_pushstring(L, "incorrect argument");
lua_error(L);
}
sum += lua_tonumber(L, i);
}
lua_pushnumber(L, sum/n); /* 最初の結果 */
lua_pushnumber(L, sum); /* 2番目の結果 */
return 2; /* 結果の数 */
}
lua_checkstack
// [-0, +0, m]
int lua_checkstack (lua_State *L, int extra);
スタックに少なくともextra
の空きスロットがあることを保証します。スタックをそのサイズまで増やすことができない場合はfalseを返します。この関数はスタックを縮小することはありません。スタックが新しいサイズよりも既に大きい場合、それは変更されません。
lua_close
// [-0, +0, -]
void lua_close (lua_State *L);
指定されたLuaステート内のすべてのオブジェクトを破壊し(該当するガーベジコレクションメタメソッドがある場合は呼び出します)、このステートによって使用されるすべての動的メモリを解放します。いくつかのプラットフォームでは、ホストプログラムが終了するとすべてのリソースが自然に解放されるため、この関数を呼び出す必要はないかもしれません。一方で、デーモンやWebサーバーなどの長時間実行されるプログラムは、不要になったらすぐにステートを解放する必要があるかもしれません。これは、サイズが大きくなりすぎるのを避けるためです。
lua_concat
// [-n, +1, e]
void lua_concat (lua_State *L, int n);
スタックの上部にあるn
個の値を連結し、それらをポップして、結果をスタックの上部に残します。n
が1の場合、結果はスタック上の単一の値です(つまり、関数は何もしません)。n
が0の場合、結果は空の文字列です。連結はLuaの通常のセマンティクスに従って行われます(§2.5.4を参照)。
lua_cpcall
// [-0, +(0|1), -]
int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);
保護モードでC関数func
を呼び出します。func
はスタックにud
を含むライトユーザーデータのみで開始します。エラーが発生した場合、lua_cpcall
はlua_pcall
と同じエラーコードを返し、スタックの上部にエラーオブジェクトを返します。そうでない場合はゼロを返し、スタックを変更しません。func
によって返されたすべての値は破棄されます。
lua_createtable
// [-0, +1, m]
void lua_createtable (lua_State *L, int narr, int nrec);
新しい空のテーブルを作成し、それをスタックにプッシュします。新しいテーブルは、narr
配列要素とnrec
非配列要素用に事前に割り当てられたスペースを持ちます。この事前割り当ては、テーブルが持つ要素の正確な数を知っている場合に便利です。それ以外の場合は、関数lua_newtable
を使用できます。
lua_dump
// [-0, +0, m]
int lua_dump (lua_State *L, lua_Writer writer, void *data);
関数をバイナリチャンクとしてダンプします。スタックの先頭にあるLua関数を受け取り、再度ロードすると元の関数と同等の関数となるバイナリチャンクを生成します。チャンクの一部を生成すると、lua_dump
は与えられたデータでそれらを書き込むために関数ライター(lua_Writer
参照)を呼び出します。
戻り値は、ライターへの最後の呼び出しによって返されたエラーコードです。0はエラーがないことを意味します。
この関数はスタックからLua関数をポップしません。
lua_equal
// [-0, +0, e]
int lua_equal (lua_State *L, int index1, int index2);
許容されるインデックスindex1
とindex2
にある2つの値が等しい場合に1を返し、Luaの==
演算子のセマンティクスに従います(つまり、メタメソッドを呼び出す可能性があります)。それ以外の場合は0を返します。いずれかのインデックスが無効である場合も0を返します。
lua_error
// [-1, +0, v]
int lua_error (lua_State *L);
Luaエラーを生成します。エラーメッセージ(実際には任意の型のLua値になり得ます)はスタックの先頭になければなりません。この関数はロングジャンプを行うため、決して戻りません(luaL_error
を参照)。
lua_gc
// [-0, +0, e]
int lua_gc (lua_State *L, int what, int data);
ガーベジコレクタを制御します。
この関数はwhat
パラメータの値に応じて、いくつかのタスクを実行します:
LUA_GCSTOP
: ガーベジコレクタを停止します。LUA_GCRESTART
: ガーベジコレクタを再起動します。LUA_GCCOLLECT
: 完全なガーベジコレクションサイクルを実行します。LUA_GCCOUNT
: Luaが使用中のメモリの現在の量(キロバイト単位)を返します。LUA_GCCOUNTB
: Luaが使用中のメモリの現在のバイト数を1024で割った余りを返します。LUA_GCSTEP
: ガーベジコレクションのインクリメンタルステップを実行します。ステップの「サイズ」はdata
(大きい値はより多くのステップを意味します)によって非指定の方法で制御されます。ステップサイズを制御したい場合は、data
の値を実験的に調整する必要があります。この関数は、ステップがガーベジコレクションサイクルを終了した場合に1を返します。LUA_GCSETPAUSE
:data
をコレクタの一時停止の新しい値として設定します(§2.10参照)。関数は一時停止の前の値を返します。LUA_GCSETSTEPMUL
:data
をコレクタのステップ乗数の新しい値として設定します(§2.10参照)。関数はステップ乗数の前の値を返します。
lua_getallocf
// [-0, +0, -]
lua_Alloc lua_getallocf (lua_State *L, void **ud);
特定のステートのメモリ割り当て関数を返します。ud
がNULLでない場合、Luaは*ud
にlua_newstate
に渡された不透明なポインタを格納します。
lua_getfenv
// [-0, +1, -]
void lua_getfenv (lua_State *L, int index);
指定されたインデックスにある値の環境テーブルをスタックにプッシュします。
lua_getfield
// [-0, +1, e]
void lua_getfield (lua_State *L, int index, const char *k);
スタックに値t[k]
をプッシュします。ここでt
は指定された有効なインデックスの値です。Luaと同様に、この関数は"index"イベントに対するメタメソッドをトリガーすることがあります(§2.8参照)。
lua_getglobal
// [-0, +1, e]
void lua_getglobal (lua_State *L, const char *name);
グローバル変数name
の値をスタックにプッシュします。マクロとして定義されています:
#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, s)
lua_getmetatable
// [-0, +(0|1), -]
int lua_getmetatable (lua_State *L, int index);
指定された許容インデックスにある値のメタテーブルをスタックにプッシュします。インデックスが無効である場合、または値にメタテーブルがない場合、関数は0を返し、スタックに何もプッシュしません。
lua_gettable
// [-1, +1, e]
void lua_gettable (lua_State *L, int index);
t[k]
の値をスタックにプッシュします。ここでt
は指定された有効なインデックスにおける値であり、k
はスタックの上部にある値です。
この関数はスタックからキーをポップします(結果の値をその場所に置きます)。Luaと同様に、この関数は"index"イベントのメタメソッドをトリガーする可能性があります(§2.8参照)。
lua_gettop
// [-0, +0, -]
int lua_gettop (lua_State *L);
スタックの最上位要素のインデックスを返します。インデックスは1から始まるため、この結果はスタック内の要素の数と等しくなります(したがって0は空のスタックを意味します)。
lua_insert
// [-1, +1, -]
void lua_insert (lua_State *L, int index);
上部の要素を指定された有効なインデックスに移動し、このインデックスより上の要素をシフトアップしてスペースを開けます。擬似インデックスでは呼び出せません。なぜなら、擬似インデックスは実際のスタック位置ではないからです。
lua_Integer
typedef ptrdiff_t lua_Integer;
Lua APIが整数値を表すために使用する型です。
デフォルトではptrdiff_t
であり、これは通常、マシンが「快適に」扱うことができる最大の符号付き整数型です。
lua_isboolean
// [-0, +0, -]
int lua_isboolean (lua_State *L, int index);
指定された許容インデックスにある値がブール型である場合は1を返し、そうでない場合は0を返します。
lua_iscfunction
// [-0, +0, -]
int lua_iscfunction (lua_State *L, int index);
指定された許容インデックスにある値がC関数であれば1を返し、そうでなければ0を返します。
lua_isfunction
// [-0, +0, -]
int lua_isfunction (lua_State *L, int index);
指定された許容インデックスにある値が関数(CまたはLuaのいずれか)であれば1を返し、そうでなければ0を返します。
lua_islightuserdata
// [-0, +0, -]
int lua_islightuserdata (lua_State *L, int index);
指定された許容インデックスにある値がライトユーザーデータであれば1を返し、そうでなければ0を返します。
lua_isnil
// [-0, +0, -]
int lua_isnil (lua_State *L, int index);
指定された許容インデックスにある値がnilであれば1を返し、そうでなければ0を返します。
lua_isnone
// [-0, +0, -]
int lua_isnone (lua_State *L, int index);
指定された許容インデックスが無効である(つまり、現在のスタックの外部の要素を指している)場合は1を返し、そうでなければ0を返します。
lua_isnoneornil
// [-0, +0, -]
int lua_isnoneornil (lua_State *L, int index);
指定された許容インデックスが無効(つまり、現在のスタックの外部の要素を指している)であるか、このインデックスの値がnilであれば1を返し、そうでなければ0を返します。
lua_isnumber
// [-0, +0, -]
int lua_isnumber (lua_State *L, int index);
指定された許容インデックスにある値が数値または数値に変換可能な文字列であれば1を返し、そうでなければ0を返します。
lua_isstring
// [-0, +0, -]
int lua_isstring (lua_State *L, int index);
指定された許容インデックスにある値が文字列または数値(数値は常に文字列に変換可能)であれば1を返し、そうでなければ0を返します。
lua_istable
// [-0, +0, -]
int lua_istable (lua_State *L, int index);
指定された許容インデックスにある値がテーブルであれば1を返し、そうでなければ0を返します。
lua_isthread
// [-0, +0, -]
int lua_isthread (lua_State *L, int index);
指定された許容インデックスにある値がスレッドであれば1を返し、そうでなければ0を返します。
lua_isuserdata
// [-0, +0, -]
int lua_isuserdata (lua_State *L, int index);
指定された許容インデックスにある値がユーザーデータ(フルまたはライト)であれば1を返し、そうでなければ0を返します。
lua_lessthan
// [-0, +0, e]
int lua_lessthan (lua_State *L, int index1, int index2);
Luaの<
演算子のセマンティクスに従い(つまり、メタメソッドを呼び出す可能性があります)、許容されるインデックスindex1
にある値がindex2
にある値より小さい場合は1を返し、そうでなければ0を返します。いずれかのインデックスが無効である場合も0を返します。
lua_load
// [-0, +1, -]
int lua_load (lua_State *L, lua_Reader reader, void *data, const char *chunkname);
Luaチャンクをロードします。エラーがなければ、lua_load
はコンパイルされたチャンクをLua関数としてスタックの上にプッシュします。そうでなければ、エラーメッセージをプッシュします。lua_load
の戻り値は以下の通りです:
- 0: エラーなし
LUA_ERRSYNTAX
: 前処理中の構文エラーLUA_ERRMEM
: メモリ割り当てエラー
この関数はチャンクをロードするだけで、実行はしません。
lua_load
はチャンクがテキストかバイナリかを自動的に検出し、それに応じてロードします(プログラムluac
を参照)。
lua_load
関数はユーザー提供のリーダー関数を使用してチャンクを読み込みます(lua_Reader
参照)。data
引数はリーダー関数に渡される不透明な値です。
chunkname
引数はチャンクに名前を与え、エラーメッセージやデバッグ情報で使用されます(§3.8参照)。
lua_newstate
// [-0, +0, -]
lua_State *lua_newstate (lua_Alloc f, void *ud);
新しい、独立したステートを作成します。ステートを作成できない(メモリ不足のため)場合はNULLを返します。f
引数はアロケータ関数で、このステートのためのすべてのメモリ割り当てはこの関数を通じて行われます。2番目の引数ud
は、Luaがすべての呼び出しでアロケータに単純に渡す不透明なポインタです。
lua_newtable
// [-0, +1, m]
void lua_newtable (lua_State *L);
新しい空のテーブルを作成し、スタックにプッシュします。これはlua_createtable(L, 0, 0)
と等価です。
lua_newthread
// [-0, +1, m]
lua_State *lua_newthread (lua_State *L);
新しいスレッドを作成し、スタックにプッシュし、この新しいスレッドを表すlua_State
へのポインタを返します。この関数によって返される新しいステートは、元のステートとすべてのグローバルオブジェクト(テーブルなど)を共有しますが、独立した実行スタックを持ちます。
スレッドを閉じるまたは破壊するための明示的な関数はありません。スレッドは、任意のLuaオブジェクトと同様に、ガーベジコレクションの対象です。
lua_newuserdata
// [-0, +1, m]
void *lua_newuserdata (lua_State *L, size_t size);
この関数は指定されたサイズの新しいメモリブロックを割り当て、そのブロックのアドレスを持つ新しいフルユーザーデータをスタックにプッシュし、このアドレスを返します。
ユーザーデータはLua内のCの値を表します。フルユーザーデータはメモリブロックを表します。それはオブジェクト(テーブルのような)です:作成する必要があり、自身のメタテーブルを持つことができ、収集されているときに検出することができます。フルユーザーデータはそれ自体(生の等価性の下で)にのみ等しいです。
Luaがgcメタメソッドを持つフルユーザーデータを収集するとき、Luaはメタメソッドを呼び出し、ユーザーデータを最終化されたとマークします。このユーザーデータが再び収集されると、Luaは対応するメモリを解放します。
lua_next
// [-1, +(2|0), e]
int lua_next (lua_State *L, int index);
スタックからキーをポップし、指定されたインデックスのテーブルからキーと値のペア(与えられたキーの「次」のペア)をプッシュします。テーブル内に他の要素がない場合、lua_next
は0を返します(何もプッシュしません)。
典型的な走査は次のようになります:
/* table is in the stack at index 't' */
lua_pushnil(L); /* 最初のキー */
while (lua_next(L, t) != 0) {
/* 'key'(インデックス-2に)と'value'(インデックス-1に)を使用 */
printf("%s - %s\n",
lua_typename(L, lua_type(L, -2)),
lua_typename(L, lua_type(L, -1)));
/* 'value'を削除し、次の反復のために'key'を保持 */
lua_pop(L, 1);
}
テーブルを走査するときは、キーが実際に文字列であることが分かっている場合を除き、キーに対してlua_tolstring
を直接呼び出さないでください。lua_tolstring
は指定されたインデックスの値を変更するため、次のlua_next
の呼び出しを混乱させます。
lua_Number
typedef double lua_Number;
Luaの数値の型です。デフォルトではdoubleですが、luaconf.hで変更することができます。
設定ファイルを通じて、数値のための別の型(例えば、floatやlong)でLuaを動作させるように変更できます。
lua_objlen
// [-0, +0, -]
size_t lua_objlen (lua_State *L, int index);
指定された許容インデックスにある値の「長さ」を返します:文字列の場合は文字列の長さ、テーブルの場合は長さ演算子('#')の結果、ユーザーデータの場合はユーザーデータに割り当てられたメモリブロックのサイズ、他の値の場合は0です。
lua_pcall
// [-(nargs + 1), +(nresults|1), -]
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);
保護モードで関数を呼び出します。
nargs
とnresults
はlua_call
と同じ意味を持ちます。呼び出し中にエラーがなければ、lua_pcall
はlua_call
と全く同じように振る舞います。しかし、エラーが発生した場合、lua_pcall
はそれをキャッチし、スタックに単一の値(エラーメッセージ)をプッシュし、エラーコードを返します。lua_call
と同様に、lua_pcall
は常に関数とその引数をスタックから削除します。
errfunc
が0の場合、スタックに返されるエラーメッセージは元のエラーメッセージと完全に同じです。それ以外の場合、errfunc
はエラーハンドラ関数のスタックインデックスです。(現在の実装では、このインデックスは擬似インデックスにはなり得ません。)ランタイムエラーの場合、この関数はエラーメッセージと共に呼び出され、その返り値がlua_pcall
によってスタックに返されるメッセージになります。
通常、エラーハンドラ関数はエラーメッセージにさらなるデバッグ情報(スタックトレースなど)を追加するために使用されます。このような情報はlua_pcall
の戻り後には収集できません。その時点ではすでにスタックが巻き戻されています。
lua_pcall
関数は成功の場合に0を返します。または以下のエラーコードのいずれか(lua.hで定義)を返します:
LUA_ERRRUN
: ランタイムエラー。LUA_ERRMEM
: メモリ割り当てエラー。この種のエラーに対しては、Luaはエラーハンドラ関数を呼び出しません。LUA_ERRERR
: エラーハンドラ関数の実行中にエラーが発生しました。
lua_pop
// [-n, +0, -]
void lua_pop (lua_State *L, int n);
スタックからn
個の要素をポップします。
lua_pushboolean
// [-0, +1, -]
void lua_pushboolean (lua_State *L, int b);
真偽値b
をスタックにプッシュします。
lua_pushcclosure
// [-n, +1, m]
void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
新しいCクロージャをスタックにプッシュします。
C関数が作成されると、それにいくつかの値を関連付けることができ、これによりCクロージャが作成されます(§3.4を参照);これらの値は、関数が呼び出されるたびに関数からアクセス可能です。C関数に値を関連付けるには、まずこれらの値をスタックにプッシュする必要があります(複数の値がある場合は、最初の値が最初にプッシュされます)。次にlua_pushcclosure
を呼び出して、C関数をスタックに作成してプッシュします。引数n
は関数に関連付けるべき値の数を示します。lua_pushcclosure
はこれらの値もスタックからポップします。
n
の最大値は255です。
lua_pushcfunction
// [-0, +1, m]
void lua_pushcfunction (lua_State *L, lua_CFunction f);
C関数をスタックにプッシュします。この関数はC関数へのポインタを受け取り、呼び出されると対応するC関数を起動する型functionのLua値をスタックにプッシュします。
Luaに登録される任意の関数は、そのパラメータを受け取り結果を返すための正しいプロトコルに従う必要があります(lua_CFunction
を参照)。
lua_pushcfunction
はマクロとして定義されています:
#define lua_pushcfunction(L,f) lua_pushcclosure(L,f,0)
lua_pushfstring
// [-0, +1, m]
const char *lua_pushfstring (lua_State *L, const char *fmt, ...);
フォーマットされた文字列をスタックにプッシュし、この文字列へのポインタを返します。C関数sprintf
に似ていますが、いくつか重要な違いがあります:
結果のためのスペースを割り当てる必要はありません。結果はLuaの文字列であり、Luaがメモリの割り当て(およびガーベージコレクションによる解放)を行います。 変換指定子はかなり制限されています。フラグ、幅、精度はありません。変換指定子は'%%'(文字列に'%'を挿入)、'%s'(サイズ制限なしのゼロ終了文字列を挿入)、'%f'(lua_Number
を挿入)、'%p'(ポインタを16進数で挿入)、'%d'(int
を挿入)、'%c'(int
を文字として挿入)のみを使用できます。
lua_pushinteger
// [-0, +1, -]
void lua_pushinteger (lua_State *L, lua_Integer n);
値n
の数値をスタックにプッシュします。
lua_pushlightuserdata
// [-0, +1, -]
void lua_pushlightuserdata (lua_State *L, void *p);
ライトユーザーデータをスタックにプッシュします。
ユーザーデータはLua内のC値を表します。ライトユーザーデータはポインタを表します。それは値(数値のような)です:作成することはありません、個別のメタテーブルを持たない、そして集められることはありません(それは決して作成されなかったので)。ライトユーザーデータは、同じCアドレスを持つ任意のライトユーザーデータと等しいです。
lua_pushliteral
// [-0, +1, m]
void lua_pushliteral (lua_State *L, const char *s);
このマクロはlua_pushlstring
と等価ですが、s
がリテラル文字列である場合のみ使用できます。これらの場合、自動的に文字列の長さを提供します。
lua_pushlstring
// [-0, +1, m]
void lua_pushlstring (lua_State *L, const char *s, size_t len);
s
が指す長さlen
の文字列をスタックにプッシュします。Luaは与えられた文字列の内部コピーを作成(または再利用)しますので、関数が戻った直後にs
のメモリを解放または再利用できます。文字列には組み込みのゼロを含めることができます。
lua_pushnil
// [-0, +1, -]
void lua_pushnil (lua_State *L);
nil
値をスタックにプッシュします。
lua_pushnumber
// [-0, +1, -]
void lua_pushnumber (lua_State *L, lua_Number n);
値n
の数値をスタックにプッシュします。
lua_pushstring
// [-0, +1, m]
void lua_pushstring (lua_State *L, const char *s);
s
が指すゼロ終了文字列をスタックにプッシュします。Luaは与えられた文字列の内部コピーを作成(または再利用)しますので、関数が戻った直後にs
のメモリを解放または再利用できます。文字列に組み込みのゼロを含むことはできず、最初のゼロで終了すると見なされます。
lua_pushthread
// [-0, +1, -]
int lua_pushthread (lua_State *L);
L
によって表されるスレッドをスタックにプッシュします。このスレッドがそのステートのメインスレッドであれば1を返します。
lua_pushvalue
// [-0, +1, -]
void lua_pushvalue (lua_State *L, int index);
指定された有効なインデックスにある要素のコピーをスタックにプッシュします。
lua_pushvfstring
// [-0, +1, m]
const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp);
lua_pushfstring
と同等ですが、可変個の引数の代わりにva_list
を受け取ります。
lua_rawequal
// [-0, +0, -]
int lua_rawequal (lua_State *L, int index1, int index2);
許容されるインデックスindex1
とindex2
の2つの値が原始的に等しい(つまり、メタメソッドを呼び出さずに)場合は1を返し、そうでなければ0を返します。いずれかのインデックスが無効である場合も0を返します。
lua_rawget
// [-1, +1, -]
void lua_rawget (lua_State *L, int index);
lua_gettable
に似ていますが、メタメソッドを使用せずに生のアクセスを行います。
lua_rawgeti
// [-0, +1, -]
void lua_rawgeti (lua_State *L, int index, int n);
指定された有効なインデックスにある値t
のt[n]
をスタックにプッシュします。アクセスは生のもので、メタメソッドは呼び出されません。
lua_rawset
// [-2, +0, m]
void lua_rawset (lua_State *L, int index);
lua_settable
に似ていますが、メタメソッドを使用せずに生の割り当てを行います。
lua_rawseti
// [-1, +0, m]
void lua_rawseti (lua_State *L, int index, int n);
与えられた有効なインデックスにある値t
で、t[n] = v
と同等の操作を行います。ここでv
はスタックのトップにある値です。
この関数はスタックから値をポップします。割り当ては生のもので、メタメソッドは呼び出されません。
lua_Reader
typedef const char * (*lua_Reader) (lua_State *L, void *data, size_t *size);
lua_load
によって使用されるリーダー関数です。別のチャンクの部分が必要になるたびに、lua_load
はそのデータパラメータとともにリーダーを呼び出します。リーダーはチャンクの新しい部分を含むメモリブロックへのポインタを返し、size
をブロックサイズに設定する必要があります。ブロックは、リーダー関数が再度呼び出されるまで存在する必要があります。チャンクの終わりを示すには、リーダーはNULL
を返すか、size
をゼロに設定する必要があります。リーダー関数はゼロより大きい任意のサイズの部分を返すことができます。
lua_register
// [-0, +0, e]
void lua_register (lua_State *L, const char *name, lua_CFunction f);
C関数f
をグローバル名name
の新しい値として設定します。マクロとして定義されています:
#define lua_register(L,n,f) \
(lua_pushcfunction(L, f), lua_setglobal(L, n))
lua_remove
// [-1, +0, -]
void lua_remove (lua_State *L, int index);
指定された有効なインデックスの要素を削除し、このインデックスより上の要素を下にシフトしてギャップを埋めます。擬似インデックスでは呼び出せません。なぜなら、擬似インデックスは実際のスタック位置ではないからです。
lua_replace
// [-1, +0, -]
void lua_replace (lua_State *L, int index);
トップ要素を指定された位置に移動し(ポップします)、他の要素をシフトせずに(したがって、指定された位置の値を置き換えます)。
lua_resume
// [-?, +?, -]
int lua_resume (lua_State *L, int narg);
指定されたスレッドでコルーチンを開始し、再開します。
コルーチンを開始するには、まず新しいスレッドを作成します(lua_newthread
を参照);次に、そのスタックにメイン関数と任意の引数をプッシュします;次にlua_resume
を呼び出し、narg
は引数の数です。この呼び出しは、コルーチンが一時停止または実行を終了すると戻ります。戻ったとき、スタックにはlua_yield
に渡されたすべての値、または本体関数によって返されたすべての値が含まれます。lua_resume
は、コルーチンが一時停止した場合はLUA_YIELD
を、コルーチンがエラーなしで実行を終了した場合は0を返し、エラーが発生した場合はエラーコードを返します(lua_pcall
を参照)。エラーが発生した場合、スタックは巻き戻されないので、デバッグAPIを使用できます。エラーメッセージはスタックのトップにあります。コルーチンを再開するには、yieldからの結果として渡す値のみをスタックに置き、lua_resume
を呼び出します。
lua_setallocf
// [-0, +0, -]
void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
指定されたステートのアロケータ関数をユーザーデータud
を持つf
に変更します。
lua_setfenv
// [-1, +0, -]
int lua_setfenv (lua_State *L, int index);
スタックからテーブルをポップし、指定されたインデックスの値の新しい環境として設定します。指定されたインデックスの値が関数、スレッド、またはユーザーデータでない場合、lua_setfenv
は0を返します。それ以外の場合は1を返します。
lua_setfield
// [-1, +0, e]
void lua_setfield (lua_State *L, int index, const char *k);
t[k] = v
と同等の操作を行います。ここでt
は与えられた有効なインデックスでの値、v
はスタックのトップにある値です。
この関数はスタックから値をポップします。Luaと同様に、この関数は"newindex"イベントのメタメソッドを起動する可能性があります(§2.8を参照)。
lua_setglobal
// [-1, +0, e]
void lua_setglobal (lua_State *L, const char *name);
スタックから値をポップし、それをグローバル名の新しい値として設定します。マクロとして定義されています:
#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, s)
lua_setmetatable
// [-1, +0, -]
int lua_setmetatable (lua_State *L, int index);
スタックからテーブルをポップし、指定された有効なインデックスの値の新しいメタテーブルとして設定します。
lua_settable
// [-2, +0, e]
void lua_settable (lua_State *L, int index);
t[k] = v
と同等の操作を行います。ここでt
は与えられた有効なインデックスでの値、v
はスタックのトップにあり、k
はトップの直下にある値です。
この関数はキーと値の両方をスタックからポップします。Luaと同様に、この関数は"newindex"イベントのメタメソッドを起動する可能性があります(§2.8を参照)。
lua_settop
// [-?, +?, -]
void lua_settop (lua_State *L, int index);
任意の有効なインデックス、または0を受け付け、スタックのトップをこのインデックスに設定します。新しいトップが古いものより大きい場合、新しい要素はnilで埋められます。インデックスが0の場合、すべてのスタック要素が削除されます。
lua_State
typedef struct lua_State lua_State;
Luaインタープリタの全状態を保持する不透明な構造体です。Luaライブラリは完全に再入可能であり、グローバル変数を持っていません。状態に関するすべての情報はこの構造体に保持されます。
この状態へのポインタは、ライブラリのすべての関数に対して最初の引数として渡されなければなりません。ただし、lua_newstateは除きます。この関数は最初からLuaの状態を作成します。
lua_status
// [-0, +0, -]
int lua_status (lua_State *L);
スレッドL
の状態を返します。
状態は、通常のスレッドの場合は0、スレッドがエラーで実行を終了した場合はエラーコード、スレッドが中断されている場合はLUA_YIELD
になります。
lua_toboolean
// [-0, +0, -]
int lua_toboolean (lua_State *L, int index);
与えられた有効なインデックスでのLua値をCのブール値(0または1)に変換します。Luaのすべてのテストと同様に、lua_toboolean
はfalseとnil以外の任意のLua値に対して1を返し、それ以外の場合は0を返します。無効なインデックスで呼び出された場合も0を返します。(実際のブール値のみを受け入れる場合は、値のタイプをテストするためにlua_isboolean
を使用します。)
lua_tocfunction
// [-0, +0, -]
lua_CFunction lua_tocfunction (lua_State *L, int index);
与えられた有効なインデックスの値をC関数に変換します。その値はC関数でなければならず、そうでない場合はNULLを返します。
lua_tointeger
// [-0, +0, -]
lua_Integer lua_tointeger (lua_State *L, int index);
与えられた有効なインデックスでのLua値を符号付き整数型lua_Integer
に変換します。Lua値は数値または数値に変換可能な文字列でなければなりません(§2.2.1を参照);そうでない場合、lua_tointeger
は0を返します。
数値が整数でない場合、それは特定されていない何らかの方法で切り捨てられます。
lua_tolstring
// [-0, +0, m]
const char *lua_tolstring (lua_State *L, int index, size_t *len);
与えられた有効なインデックスのLua値をCの文字列に変換します。len
がNULLでない場合、文字列の長さを*len
に設定します。Lua値は文字列または数値でなければならず、そうでない場合は関数はNULLを返します。値が数値の場合、lua_tolstring
はスタック内の実際の値を文字列にも変更します。(この変更は、テーブル走査中にキーにlua_tolstring
が適用されるとlua_next
を混乱させます。)
lua_tolstring
はLuaステート内の文字列への完全にアラインされたポインタを返します。この文字列は最後の文字の後に常にゼロ('\0')を持ちます(C言語のように)、しかし、本文中に他のゼロを含むことができます。Luaにはガーベージコレクションがあるため、スタックから対応する値が削除された後にlua_tolstring
によって返されるポインタが有効であることは保証されません。
lua_tonumber
// [-0, +0, -]
lua_Number lua_tonumber (lua_State *L, int index);
与えられた有効なインデックスのLua値をCのタイプlua_Number
に変換します(lua_Number
を参照)。Lua値は数値または数値に変換可能な文字列でなければなりません(§2.2.1を参照);そうでない場合、lua_tonumber
は0を返します。
lua_topointer
// [-0, +0, -]
const void *lua_topointer (lua_State *L, int index);
与えられた有効なインデックスの値を一般的なCポインタ(void*
)に変換します。値はユーザーデータ、テーブル、スレッド、または関数である可能性があります;そうでない場合、lua_topointer
はNULLを返します。異なるオブジェクトは異なるポインタを与えます。ポインタを元の値に戻す方法はありません。
通常、この関数はデバッグ情報用にのみ使用されます。
lua_tostring
// [-0, +0, m]
const char *lua_tostring (lua_State *L, int index);
len
がNULLに等しいlua_tolstring
と同等です。
lua_tothread
// [-0, +0, -]
lua_State *lua_tothread (lua_State *L, int index);
与えられた有効なインデックスの値をLuaスレッド(lua_State*
として表される)に変換します。この値はスレッドでなければならず、そうでない場合、関数はNULLを返します。
lua_touserdata
// [-0, +0, -]
void *lua_touserdata (lua_State *L, int index);
与えられた有効なインデックスの値が完全なユーザーデータの場合、そのブロックアドレスを返します。値がライトユーザーデータの場合、そのポインタを返します。それ以外の場合はNULLを返します。
lua_type
// [-0, +0, -]
int lua_type (lua_State *L, int index);
与えられた有効なインデックスの値の型を返します。非有効なインデックスの場合はLUA_TNONE
を返します(つまり、"空"のスタック位置へのインデックス)。lua_type
によって返される型は、lua.h
で定義された以下の定数によってコード化されます:LUA_TNIL
, LUA_TNUMBER
, LUA_TBOOLEAN
, LUA_TSTRING
, LUA_TTABLE
, LUA_TFUNCTION
, LUA_TUSERDATA
, LUA_TTHREAD
, そしてLUA_TLIGHTUSERDATA
。
lua_typename
// [-0, +0, -]
const char *lua_typename (lua_State *L, int tp);
tp
でエンコードされた型の名前を返します。tp
はlua_type
によって返された値でなければなりません。
lua_Writer
typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
lua_dump
によって使用されるライター関数の型です。チャンクの別の部分を生成するたびに、lua_dump
はライターを呼び出し、書き込まれるバッファ(p
)、そのサイズ(sz
)、およびlua_dump
に供給されたデータパラメータを渡します。
ライターはエラーコードを返します:0はエラーがないことを意味し、他の値はエラーを意味し、lua_dump
がライターを再び呼び出すのを停止します。
lua_xmove
// [-?, +?, -]
void lua_xmove (lua_State *from, lua_State *to, int n);
同じグローバル状態の異なるスレッド間で値を交換します。
この関数はfrom
のスタックからn
個の値をポップし、それらをto
のスタックにプッシュします。
lua_yield
// [-?, +?, -]
int lua_yield (lua_State *L, int nresults);
コルーチンを中断します。
この関数はC関数のリターン式としてのみ呼び出されるべきです:
return lua_yield (L, nresults);
C関数がこの方法でlua_yield
を呼び出すと、実行中のコルーチンはその実行を中断し、このコルーチンを開始したlua_resume
の呼び出しが戻ります。nresults
パラメータは、lua_resume
への結果としてスタックから渡される値の数です。
3.8 – デバッグインターフェース
Luaには組み込みのデバッグ機能はありません。代わりに、関数やフックを通じて特別なインターフェースを提供しています。このインターフェースは、インタープリターからの「内部情報」を必要とするさまざまな種類のデバッガー、プロファイラー、その他のツールの構築を可能にします。
lua_Debug
typedef struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) */
const char *what; /* (S) */
const char *source; /* (S) */
int currentline; /* (l) */
int nups; /* (u) アップバリューの数 */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
other fields
} lua_Debug;
アクティブな関数に関するさまざまな情報を伝達するために使用される構造体です。lua_getstack
はこの構造体のプライベート部分のみを埋め、後で使用するためです。lua_Debug
の他のフィールドを有用な情報で埋めるには、lua_getinfo
を呼び出します。
lua_Debug
構造体のフィールドは以下の意味を持ちます:
source
: 関数が文字列で定義されている場合、source
はその文字列です。ファイルで定義されている場合、source
は'@'
に続いてファイル名から始まります。short_src
:source
の「印刷可能な」バージョンで、エラーメッセージで使用されます。linedefined
: 関数の定義が始まる行番号です。lastlinedefined
: 関数の定義が終わる行番号です。what
: 関数がLua関数であれば"Lua"、C関数であれば"C"、チャンクのメイン部分であれば"main"、末尾呼び出しを行った関数であれば"tail"の文字列です。後者の場合、Luaにはその関数についての他の情報はありません。currentline
: 実行中の関数がある現在の行です。行情報が利用できない場合、currentline
は-1に設定されます。name
: 与えられた関数の適切な名前です。Luaの関数はファーストクラスの値であるため、固定の名前を持っていません:いくつかの関数は複数のグローバル変数の値になることがあり、他のものはテーブルのフィールドにのみ保存されることがあります。lua_getinfo
関数は、適切な名前を見つけるために関数がどのように呼び出されたかをチェックします。名前を見つけることができない場合、name
はNULLに設定されます。namewhat
:name
フィールドを説明します。namewhat
の値は、関数の呼び出し方によって「global」、「local」、「method」、「field」、「upvalue」、または「」(空の文字列)になります。(Luaは他のオプションが適用されないように見える場合に空の文字列を使用します。)nups
: 関数のアップバリューの数です。
lua_gethook
// [-0, +0, -]
lua_Hook lua_gethook (lua_State *L);
現在のフック関数を返します。
lua_gethookcount
// [-0, +0, -]
int lua_gethookcount (lua_State *L);
現在のフックカウントを返します。
lua_gethookmask
// [-0, +0, -]
int lua_gethookmask (lua_State *L);
現在のフックマスクを返します。
lua_getinfo
// [-(0|1), +(0|1|2), m]
int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
特定の関数または関数呼び出しについての情報を返します。
関数呼び出しについての情報を取得するには、ar
パラメータは、以前にlua_getstack
によって記入された有効なアクティベーションレコードである必要があります、またはフックに引数として与えられる必要があります(lua_Hook
を参照)。
関数についての情報を取得するには、それをスタックにプッシュし、what
文字列を文字'>'
で開始します。(その場合、lua_getinfo
はスタックの上にある関数をポップします。)例えば、関数f
がどの行で定義されたかを知るには、次のコードを書くことができます:
lua_Debug ar;
lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* get global 'f' */
lua_getinfo(L, ">S", &ar);
printf("%d\n", ar.linedefined);
what
文字列の各文字は、構造体ar
の特定のフィールドを記入するか、スタックに値をプッシュすることを選択します:
'n'
:name
とnamewhat
フィールドを記入します。'S'
:source
、short_src
、linedefined
、lastlinedefined
、およびwhat
フィールドを記入します。'l'
:currentline
フィールドを記入します。'u'
:nups
フィールドを記入します。'f'
: 与えられたレベルで実行中の関数をスタックにプッシュします。'L'
: 関数で有効な行の番号がインデックスであるテーブルをスタックにプッシュします。(有効な行とは、コードが関連付けられている行、つまり、ブレークポイントを置くことができる行です。無効な行には空行やコメントが含まれます。)
この関数はエラーが発生した場合(例えば、what
で無効なオプションがある場合)に0を返します。
lua_getlocal
// [-0, +(0|1), -]
const char *lua_getlocal (lua_State *L, lua_Debug *ar, int n);
与えられたアクティベーションレコードのローカル変数についての情報を取得します。ar
パラメータは、以前のlua_getstack
の呼び出しによって記入された有効なアクティベーションレコードでなければなりません、またはフックへの引数として与えられる必要があります(lua_Hook
参照)。n
インデックスは、調べるローカル変数を選択します(1は最初のパラメータまたはアクティブなローカル変数であり、最後のアクティブなローカル変数まで続きます)。lua_getlocal
は変数の値をスタックにプッシュし、その名前を返します。
'('
(開き括弧)で始まる変数名は、内部変数(ループ制御変数、一時変数、C関数のローカル変数)を表します。
インデックスがアクティブなローカル変数の数を超える場合は、NULL(何もプッシュせず)を返します。
lua_getstack
// [-0, +0, -]
int lua_getstack (lua_State *L, int level, lua_Debug *ar);
インタープリタのランタイムスタックについての情報を取得します。
この関数は、与えられたレベルで実行中の関数のアクティベーションレコードの識別をlua_Debug
構造体の部分に記入します。レベル0は現在実行中の関数であり、レベルn+1はレベルnを呼び出した関数です。エラーがない場合、lua_getstack
は1を返します。スタックの深さよりも大きいレベルで呼び出された場合は0を返します。
lua_getupvalue
// [-0, +(0|1), -]
const char *lua_getupvalue (lua_State *L, int funcindex, int n);
クロージャのアップバリューについての情報を取得します。(Lua関数の場合、アップバリューは関数が使用する外部のローカル変数であり、結果としてクロージャに含まれます。)lua_getupvalue
はアップバリューのインデックスnを取得し、アップバリューの値をスタックにプッシュし、その名前を返します。funcindex
はスタック内のクロージャを指します。(アップバリューには特定の順序がなく、関数全体を通してアクティブです。したがって、任意の順序で番号付けされます。)
インデックスがアップバリューの数を超える場合、NULL(何もプッシュせず)を返します。C関数の場合、この関数はすべてのアップバリューの名前として空の文字列""
を使用します。
lua_Hook
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
デバッグフック関数のための型です。
フックが呼び出されるとき、そのar
引数のevent
フィールドはフックをトリガーした特定のイベントに設定されます。Luaはこれらのイベントを次の定数で識別します:LUA_HOOKCALL
, LUA_HOOKRET
, LUA_HOOKTAILRET
, LUA_HOOKLINE
, LUA_HOOKCOUNT
。さらに、行イベントの場合、currentline
フィールドも設定されます。ar
の他のフィールドの値を取得するには、フックはlua_getinfo
を呼び出さなければなりません。戻りイベントの場合、event
はLUA_HOOKRET
(通常の値)またはLUA_HOOKTAILRET
になります。後者の場合、Luaはテールコールを行った関数からの戻りをシミュレートしています。この場合、lua_getinfo
を呼び出すことは無意味です。
Luaがフックを実行している間、他のフックへの呼び出しは無効になります。したがって、フックがLuaを呼び出して関数やチャンクを実行する場合、この実行はフックへの呼び出しなしで行われます。
lua_sethook
// [-0, +0, -]
int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
デバッグフック関数を設定します。
引数f
はフック関数です。mask
はフックが呼び出されるイベントを指定し、LUA_MASKCALL
, LUA_MASKRET
, LUA_MASKLINE
, LUA_MASKCOUNT
の定数のビット単位のORによって形成されます。count
引数は、mask
がLUA_MASKCOUNT
を含む場合にのみ意味があります。各イベントについて、フックは以下に説明されるように呼び出されます:
- コールフック:インタプリタが関数を呼び出すときに呼び出されます。フックはLuaが新しい関数に入った直後、関数がその引数を得る前に呼び出されます。
- 戻りフック:インタプリタが関数から戻るときに呼び出されます。フックはLuaが関数を離れる直前に呼び出されます。関数によって返される値にアクセスすることはできません。
- ラインフック:インタプリタが新しいコード行の実行を開始しようとするとき、またはコード内で後戻りするとき(同じ行に戻る場合でも)に呼び出されます。(このイベントはLuaがLua関数を実行している間のみ発生します。)
- カウントフック:インタプリタがカウント命令ごとに実行するときに呼び出されます。(このイベントはLuaがLua関数を実行している間のみ発生します。)
フックはmask
をゼロに設定することで無効になります。
lua_setlocal
// [-(0|1), +0, -]
const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);
与えられたアクティベーションレコードのローカル変数の値を設定します。パラメータar
とn
はlua_getlocal
(lua_getlocal
を参照)と同じです。lua_setlocal
はスタックのトップにある値を変数に割り当て、その名前を返します。また、スタックから値をポップします。
インデックスがアクティブなローカル変数の数を超える場合は、NULL(何もポップせず)を返します。
lua_setupvalue
// [-(0|1), +0, -]
const char *lua_setupvalue (lua_State *L, int funcindex, int n);
クロージャのアップバリューの値を設定します。スタックのトップにある値をアップバリューに割り当て、その名前を返します。値もスタックからポップします。パラメータfuncindex
とn
はlua_getupvalue
(lua_getupvalue
を参照)と同じです。
インデックスがアップバリューの数を超える場合は、NULL(何もポップせず)を返します。
4 – 補助ライブラリ
補助ライブラリは、CとLuaをインターフェースするための便利な関数をいくつか提供します。基本APIがCとLuaの間の全てのインタラクションのための原始的な関数を提供するのに対し、補助ライブラリはいくつかの共通タスクのための高レベル関数を提供します。
補助ライブラリの全関数はヘッダーファイルlauxlib.h
に定義されており、接頭辞luaL_
を持っています。
補助ライブラリの全関数は基本APIの上に構築されているため、このAPIで実行できないことを提供するものではありません。
補助ライブラリのいくつかの関数は、C関数の引数をチェックするために使用されます。これらの関数の名前は常にluaL_check*
またはluaL_opt*
です。これらの関数は、チェックが満たされない場合にエラーをスローします。エラーメッセージが引数用にフォーマットされているため(例: "bad argument #1")、これらの関数を他のスタック値に対して使用すべきではありません。
4.1 – 関数と型
ここでは補助ライブラリの全ての関数と型をアルファベット順にリストアップします。
luaL_addchar
// [-0, +0, m]
void luaL_addchar (luaL_Buffer *B, char c);
文字c
をバッファB
に追加します(luaL_Buffer
を参照)。
luaL_addlstring
// [-0, +0, m]
void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);
長さl
の文字列s
をバッファB
に追加します(luaL_Buffer
を参照)。文字列には組み込みのゼロを含むことができます。
luaL_addsize
// [-0, +0, m]
void luaL_addsize (luaL_Buffer *B, size_t n);
以前にバッファ領域にコピーされた長さn
の文字列をバッファB
に追加します(luaL_Buffer
を参照)。
luaL_addstring
// [-0, +0, m]
void luaL_addstring (luaL_Buffer *B, const char *s);
ゼロ終端文字列s
をバッファB
に追加します(luaL_Buffer
を参照)。文字列には組み込みのゼロを含むことはできません。
luaL_addvalue
[-1, +0, m]
void luaL_addvalue (luaL_Buffer *B);
スタックのトップにある値をバッファB
に追加します(luaL_Buffer
を参照)。値をポップします。
これは文字列バッファに対して呼び出すことができ(そして呼び出す必要がある)唯一の関数です。バッファに追加する値がスタック上に余分に存在する必要があります。
luaL_argcheck
// [-0, +0, v]
void luaL_argcheck (lua_State *L, int cond, int narg, const char *extramsg);
cond
が真であることを確認します。そうでない場合、以下のメッセージでエラーを発生させます。ここでfunc
はコールスタックから取得されます:
<func>への引数#<narg>が不正です(<extramsg>)
luaL_argerror
// [-0, +0, v]
int luaL_argerror (lua_State *L, int narg, const char *extramsg);
以下のメッセージでエラーを発生させます。ここでfunc
はコールスタックから取得されます:
<func>への引数#<narg>が不正です(<extramsg>)
この関数は決して返りませんが、C関数内でreturn luaL_argerror(args)
として使用するのが一般的な慣習です。
luaL_Buffer
typedef struct luaL_Buffer luaL_Buffer;
文字列バッファの型です。
文字列バッファを使用すると、CコードでLua文字列を部分的に構築できます。使用パターンは次のとおりです:
まず、luaL_Buffer
型の変数b
を宣言します。 次に、luaL_buffinit(L, &b)
を呼び出して初期化します。 次に、luaL_add*
関数を呼び出してバッファに文字列片を追加します。 最後にluaL_pushresult(&b)
を呼び出します。この呼び出しは最終的な文字列をスタックのトップに残します。 通常の操作中に、文字列バッファはスタックスロットを可変個数使用します。そのため、バッファを使用している間、スタックのトップがどこにあるかを知っているとは限りません。バッファ操作の間にスタックを使用する場合は、その使用がバランスを取っている限り(つまり、バッファ操作を呼び出すときにスタックが前回のバッファ操作直後のレベルにある限り)、使用することができます(唯一の例外はluaL_addvalue
です)。luaL_pushresult
を呼び出した後、スタックはバッファが初期化されたときのレベルに戻り、そのトップに最終的な文字列が置かれます。
luaL_buffinit
// [-0, +0, -]
void luaL_buffinit (lua_State *L, luaL_Buffer *B);
バッファB
を初期化します。この関数は空間を割り当てません。バッファは変数として宣言される必要があります(luaL_Buffer
を参照)。
luaL_callmeta
// [-0, +(0|1), e]
int luaL_callmeta (lua_State *L, int obj, const char *e);
メタメソッドを呼び出します。
インデックスobj
のオブジェクトにメタテーブルがあり、このメタテーブルにフィールドe
がある場合、この関数はこのフィールドを呼び出し、オブジェクトを唯一の引数として渡します。この場合、この関数は1を返し、スタックに呼び出しによって返された値をプッシュします。メタテーブルやメタメソッドがない場合、この関数は0を返します(スタックに値をプッシュせず)。
luaL_checkany
// [-0, +0, v]
void luaL_checkany (lua_State *L, int narg);
位置narg
に任意の型(nilを含む)の引数があるかどうかをチェックします。
luaL_checkint
// [-0, +0, v]
int luaL_checkint (lua_State *L, int narg);
関数の引数narg
が数値であるか確認し、その数値をint
にキャストして返します。
luaL_checkinteger
// [-0, +0, v]
lua_Integer luaL_checkinteger (lua_State *L, int narg);
関数の引数narg
が数値であるか確認し、その数値をlua_Integer
にキャストして返します。
luaL_checklong
// [-0, +0, v]
long luaL_checklong (lua_State *L, int narg);
関数の引数narg
が数値であるか確認し、その数値をlong
にキャストして返します。
luaL_checklstring
// [-0, +0, v]
const char *luaL_checklstring (lua_State *L, int narg, size_t *l);
関数の引数narg
が文字列であるか確認し、その文字列を返します。l
がNULL
でなければ、その文字列の長さを*l
に設定します。
この関数は結果を得るためにlua_tolstring
を使用するため、その関数のすべての変換と注意点がここに適用されます。
luaL_checknumber
// [-0, +0, v]
lua_Number luaL_checknumber (lua_State *L, int narg);
関数の引数narg
が数値であるか確認し、その数値を返します。
luaL_checkoption
// [-0, +0, v]
int luaL_checkoption (lua_State *L, int narg, const char *def, const char *const lst[]);
関数の引数narg
が文字列であるか確認し、その文字列を配列lst
(NULLで終了する必要があります)で検索します。文字列が見つかった配列内のインデックスを返します。引数が文字列でない場合や文字列が見つからない場合はエラーを発生させます。
def
がNULL
でない場合、この関数は引数narg
が存在しない場合やnil
である場合にデフォルト値としてdef
を使用します。
これは文字列をCの列挙型にマッピングするのに便利な関数です(Luaライブラリでは、オプションを選択するために数値の代わりに文字列を使用するのが通常の慣習です)。
luaL_checkstack
// [-0, +0, v]
void luaL_checkstack (lua_State *L, int sz, const char *msg);
スタックサイズをtop + sz
要素まで増やし、スタックをそのサイズまで増やせない場合にはエラーを発生させます。msg
はエラーメッセージに追加するテキストです。
luaL_checkstring
// [-0, +0, v]
const char *luaL_checkstring (lua_State *L, int narg);
関数の引数narg
が文字列であるか確認し、その文字列を返します。
この関数は結果を得るためにlua_tolstring
を使用するので、その関数のすべての変換と注意点がここに適用されます。
luaL_checktype
// [-0, +0, v]
void luaL_checktype (lua_State *L, int narg, int t);
関数の引数narg
の型がt
であるか確認します。t
の型のエンコーディングについてはlua_type
を参照してください。
luaL_checkudata
// [-0, +0, v]
void *luaL_checkudata (lua_State *L, int narg, const char *tname);
関数の引数narg
が型tname
のユーザーデータであるか確認します(luaL_newmetatable
を参照)。
luaL_dofile
// [-0, +?, m]
int luaL_dofile (lua_State *L, const char *filename);
指定されたファイルをロードして実行します。以下のマクロとして定義されています:
(luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))
エラーがなければ0を返し、エラーがある場合は1を返します。
luaL_dostring
// [-0, +?, m]
int luaL_dostring (lua_State *L, const char *str);
指定された文字列をロードして実行します。以下のマクロとして定義されています:
(luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))
エラーがなければ0を返し、エラーがある場合は1を返します。
luaL_error
// [-0, +0, v]
int luaL_error (lua_State *L, const char *fmt, ...);
エラーを発生させます。エラーメッセージの形式はfmt
と追加の引数によって指定され、lua_pushfstring
のルールに従います。この関数はエラーが発生したファイル名と行番号をメッセージの最初に追加します(この情報が利用可能な場合)。
この関数は戻り値を返しませんが、C関数内でreturn luaL_error(args);
として使用するのが一般的です。
luaL_getmetafield
// [-0, +(0|1), m]
int luaL_getmetafield (lua_State *L, int obj, const char *e);
インデックスobj
のオブジェクトのメタテーブルからフィールドe
をスタックにプッシュします。オブジェクトにメタテーブルがない場合、またはメタテーブルにこのフィールドがない場合、0を返し何もプッシュしません。
luaL_getmetatable
// [-0, +1, -]
void luaL_getmetatable (lua_State *L, const char *tname);
レジストリ内のtname
名で関連付けられたメタテーブルをスタックにプッシュします(luaL_newmetatable
を参照)。
luaL_gsub
// [-0, +1, m]
const char *luaL_gsub (lua_State *L, const char *s, const char *p, const char *r);
文字列s
の中の文字列p
の出現を文字列r
で置換することにより、文字列s
のコピーを作成します。結果の文字列をスタックにプッシュし、それを返します。
luaL_loadbuffer
// [-0, +1, m]
int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz, const char *name);
バッファをLuaチャンクとしてロードします。この関数はlua_load
を使用して、buff
で指されたバッファ内のチャンクをサイズsz
でロードします。
この関数はlua_load
と同じ結果を返します。name
はデバッグ情報やエラーメッセージ用のチャンク名です。
luaL_loadfile
// [-0, +1, m]
int luaL_loadfile (lua_State *L, const char *filename);
ファイルをLuaチャンクとしてロードします。この関数はlua_load
を使用してfilename
で指定されたファイル内のチャンクをロードします。filename
がNULLの場合、標準入力からロードします。ファイルの最初の行が#
で始まる場合は無視されます。
この関数はlua_load
と同じ結果を返しますが、ファイルを開けない/読み取れない場合の追加のエラーコードLUA_ERRFILEを持っています。
lua_load
と同様に、この関数はチャンクをロードするだけで、実行はしません。
luaL_loadstring
// [-0, +1, m]
int luaL_loadstring (lua_State *L, const char *s);
文字列をLuaチャンクとしてロードします。この関数はlua_load
を使用して、ゼロ終端文字列s
内のチャンクをロードします。
この関数はlua_load
と同じ結果を返します。
また、lua_load
と同様に、この関数はチャンクをロードするだけで、実行はしません。
luaL_newmetatable
// [-0, +1, m]
int luaL_newmetatable (lua_State *L, const char *tname);
レジストリにtname
というキーが既に存在する場合、0を返します。そうでない場合、ユーザーデータのメタテーブルとして使用される新しいテーブルを作成し、tname
のキーでレジストリに追加し、1を返します。
どちらの場合も、レジストリ内のtname
に関連付けられた最終的な値をスタックにプッシュします。
luaL_newstate
// [-0, +0, -]
lua_State *luaL_newstate (void);
新しいLuaステートを作成します。標準のC realloc関数に基づくアロケータを使用してlua_newstate
を呼び出し、致命的なエラーが発生した場合に標準エラー出力にエラーメッセージを出力するパニック関数(lua_atpanic
を参照)を設定します。
新しいステートを返すか、メモリ割り当てエラーがある場合はNULLを返します。
luaL_openlibs
// [-0, +0, m]
void luaL_openlibs (lua_State *L);
指定されたステートにすべての標準Luaライブラリを開きます。
luaL_optint
// [-0, +0, v]
int luaL_optint (lua_State *L, int narg, int d);
関数の引数narg
が数値の場合、この数値をint型にキャストして返します。この引数が存在しないかnilの場合はd
を返します。そうでない場合、エラーを発生させます。
luaL_optinteger
// [-0, +0, v]
lua_Integer luaL_optinteger (lua_State *L, int narg, lua_Integer d);
関数の引数narg
が数値の場合、その数値をlua_Integer
型にキャストして返します。この引数が欠けている場合やnil
の場合は、d
を返します。それ以外の場合はエラーを発生させます。
luaL_optlong
// [-0, +0, v]
long luaL_optlong (lua_State *L, int narg, long d);
関数の引数narg
が数値の場合、その数値をlong
型にキャストして返します。この引数が欠けている場合やnil
の場合は、d
を返します。それ以外の場合はエラーを発生させます。
luaL_optlstring
// [-0, +0, v]
const char *luaL_optlstring (lua_State *L, int narg, const char *d, size_t *l);
関数の引数narg
が文字列の場合、その文字列を返します。この引数が欠けている場合やnil
の場合は、d
を返します。それ以外の場合はエラーを発生させます。
l
がNULL
ではない場合、結果の長さで*l
を埋めます。
luaL_optnumber
// [-0, +0, v]
lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);
関数の引数narg
が数値の場合、その数値を返します。この引数が欠けている場合やnil
の場合は、d
を返します。それ以外の場合はエラーを発生させます。
luaL_optstring
// [-0, +0, v]
const char *luaL_optstring (lua_State *L, int narg, const char *d);
関数の引数narg
が文字列の場合、その文字列を返します。この引数が欠けている場合やnil
の場合は、d
を返します。それ以外の場合はエラーを発生させます。
luaL_prepbuffer
// [-0, +0, -]
char *luaL_prepbuffer (luaL_Buffer *B);
バッファB
に追加される文字列をコピーするための、サイズLUAL_BUFFERSIZE
のスペースへのアドレスを返します(luaL_Buffer
を参照)。このスペースに文字列をコピーした後、実際にバッファに追加するためにはluaL_addsize
を文字列のサイズで呼び出す必要があります。
luaL_pushresult
// [-?, +1, m]
void luaL_pushresult (luaL_Buffer *B);
バッファB
の使用を終了し、最終的な文字列をスタックのトップに残します。
luaL_ref
// [-1, +0, m]
int luaL_ref (lua_State *L, int t);
スタックのトップにあるオブジェクトのために、インデックスt
のテーブル内に参照を作成し、返します(そしてそのオブジェクトをポップします)。
参照とはユニークな整数キーです。テーブルt
に手動で整数キーを追加しない限り、luaL_ref
は返すキーの一意性を保証します。参照r
によって参照されるオブジェクトは、lua_rawgeti(L, t, r)
を呼び出すことで取得できます。関数luaL_unref
は参照とそれに関連付けられたオブジェクトを解放します。
スタックのトップにあるオブジェクトがnil
の場合、luaL_ref
は定数LUA_REFNIL
を返します。定数LUA_NOREF
は、luaL_ref
によって返される任意の参照と異なることが保証されています。
luaL_Reg
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;
luaL_register
によって登録される関数の配列の型です。name
は関数名で、func
は関数へのポインタです。luaL_Reg
の配列は、name
とfunc
の両方がNULL
であるセンチネルエントリで終了する必要があります。
luaL_register
// [-(0|1), +1, m]
void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l);
ライブラリをオープンします。
libname
がNULL
に等しい場合、単にリストl
内のすべての関数(luaL_Reg
を参照)をスタックのトップにあるテーブルに登録します。
libname
が非null
で呼び出された場合、luaL_register
は新しいテーブルt
を作成し、グローバル変数libname
の値として設定し、package.loaded[libname]
の値として設定し、リストl
のすべての関数をそれに登録します。package.loaded[libname]
や変数libname
にテーブルがある場合は、新しいテーブルを作成する代わりにこのテーブルを再利用します。
いずれの場合も、関数はテーブルをスタックのトップに残します。
luaL_typename
// [-0, +0, -]
const char *luaL_typename (lua_State *L, int index);
指定されたインデックスの値の型の名前を返します。
luaL_typerror
// [-0, +0, v]
int luaL_typerror (lua_State *L, int narg, const char *tname);
以下のようなメッセージでエラーを生成します:
location: bad argument narg to 'func' (tname expected, got rt)
ここでlocation
はluaL_where
によって生成され、func
は現在の関数の名前であり、rt
は実際の引数の型名です。
luaL_unref
// [-0, +0, -]
void luaL_unref (lua_State *L, int t, int ref);
インデックスt
のテーブルから参照ref
を解放します(luaL_ref
を参照)。エントリはテーブルから削除されるので、参照されたオブジェクトは回収されることができます。参照ref
も再利用のために解放されます。
ref
がLUA_NOREF
またはLUA_REFNIL
の場合、luaL_unref
は何も行いません。
luaL_where
// [-0, +1, m]
void luaL_where (lua_State *L, int lvl);
呼び出しスタックのレベルlvl
での制御の現在位置を識別する文字列をスタックにプッシュします。通常、この文字列は以下のフォーマットを持っています:
chunkname:currentline:
レベル0は実行中の関数であり、レベル1は実行中の関数を呼び出した関数です。
この関数はエラーメッセージのプレフィックスを作成するために使用されます。
5 – 標準ライブラリ
標準Luaライブラリは、C APIを直接通じて実装された便利な関数を提供します。これらの関数の中には、言語に不可欠なサービスを提供するもの(例えば、typeやgetmetatable)、"外部"サービスへのアクセスを提供するもの(例えば、入出力)、Lua自体で実装可能だが、非常に有用であったり、Cでの実装を正当化する重要なパフォーマンス要件を持つもの(例えば、table.sort)があります。
すべてのライブラリは公式のC APIを通じて実装され、個別のCモジュールとして提供されます。現在、Luaには以下の標準ライブラリがあります:
- 基本ライブラリ(コルーチンサブライブラリを含む)
- パッケージライブラリ
- 文字列操作
- テーブル操作
- 数学関数(sin、logなど)
- 入出力
- オペレーティングシステムの機能
- デバッグ機能
基本ライブラリとパッケージライブラリを除き、各ライブラリはすべての関数をグローバルテーブルのフィールドまたはそのオブジェクトのメソッドとして提供します。
これらのライブラリにアクセスするには、CホストプログラムがluaL_openlibs
関数を呼び出す必要があります。この関数はすべての標準ライブラリを開きます。代わりに、luaopen_base
(基本ライブラリのため)、luaopen_package
(パッケージライブラリのため)、luaopen_string
(文字列ライブラリのため)、luaopen_table
(テーブルライブラリのため)、luaopen_math
(数学ライブラリのため)、luaopen_io
(入出力ライブラリのため)、luaopen_os
(オペレーティングシステムライブラリのため)、そしてluaopen_debug
(デバッグライブラリのため)を呼び出すことにより、個別に開くこともできます。これらの関数はlualib.h
に宣言されており、直接呼び出すべきではありません。他のLua C関数と同様に、例えばlua_call
を使用して呼び出す必要があります。
5.1 – 基本関数
基本ライブラリは、Luaにいくつかのコア関数を提供します。アプリケーションにこのライブラリを含めない場合は、その機能の一部を実装する必要があるかどうかを慎重に確認する必要があります。
assert (v [, message])
引数v
の値が偽(すなわち、nil
またはfalse
)の場合にエラーを発生させます。それ以外の場合は、すべての引数を返します。message
はエラーメッセージで、省略された場合は「assertion failed!」がデフォルトです。
collectgarbage ([opt [, arg]])
この関数はガベージコレクタへの汎用インターフェイスです。最初の引数opt
に応じて異なる機能を実行します:
- "collect": 完全なガベージコレクションサイクルを実行します。これがデフォルトオプションです。
- "stop": ガベージコレクタを停止します。
- "restart": ガベージコレクタを再起動します。
- "count": Luaによって使用されている合計メモリ(キロバイト単位)を返します。
- "step": ガベージコレクションステップを実行します。ステップの「サイズ」は
arg
によって制御されます(大きな値はより多くのステップを意味します)が、具体的な方法は指定されていません。ステップサイズを制御したい場合は、arg
の値を実験的に調整する必要があります。コレクションサイクルが終了した場合はtrueを返します。 - "setpause": ガベージコレクタの一時停止の新しい値として
arg
を設定します(§2.10参照)。一時停止の前の値を返します。 - "setstepmul": ガベージコレクタのステップ乗数の新しい値として
arg
を設定します(§2.10参照)。ステップの前の値を返します。
dofile ([filename])
指定されたファイルを開き、その内容をLuaチャンクとして実行します。引数なしで呼び出された場合、dofile
は標準入力(stdin)の内容を実行します。チャンクによって返されたすべての値を返します。エラーが発生した場合、dofile
はその呼び出し元にエラーを伝播します(つまり、dofile
は保護モードで実行されません)。
error (message [, level])
最後に呼ばれた保護された関数を終了させ、message
をエラーメッセージとして返します。error
関数は決して戻りません。
通常、error
はメッセージの先頭にエラーの位置に関する情報を追加します。level
引数はエラーの位置を取得する方法を指定します。レベル1(デフォルト)では、エラー位置はerror
関数が呼び出された場所です。レベル2は、error
を呼び出した関数が呼び出された場所にエラーを指摘します。そして以下同様です。レベル0を渡すと、メッセージにエラー位置情報を追加することが避けられます。
_G
グローバル環境を保持するグローバル変数(関数ではありません)です(つまり、_G._G = _G)。Lua自体はこの変数を使用しません。その値を変更しても、環境には影響しませんし、その逆も同様です。(環境を変更するにはsetfenv
を使用します。)
getfenv ([f])
関数が使用している現在の環境を返します。f
はLua関数またはスタックレベルでの関数を指定する数値です:レベル1はgetfenv
を呼び出している関数です。指定された関数がLua関数でない場合、またはf
が0の場合、getfenv
はグローバル環境を返します。f
のデフォルトは1です。
getmetatable (object)
オブジェクトにメタテーブルがない場合、nilを返します。それ以外の場合、オブジェクトのメタテーブルに"__metatable"
フィールドがある場合、関連付けられた値を返します。それ以外の場合は、指定されたオブジェクトのメタテーブルを返します。
ipairs (t)
イテレータ関数、テーブルt
、0の3つの値を返し、次の構成
for i,v in ipairs(t) do body end
はテーブルのペア(1,t[1])、(2,t[2])、···を、テーブルから欠落している最初の整数キーまで繰り返します。
load (func [, chunkname])
関数func
を使用してチャンクを読み込み、そのピースを取得します。func
への各呼び出しは、前の結果と連結される文字列を返す必要があります。空の文字列、nil、または値がないことを返すと、チャンクの終わりを示します。
エラーがなければ、コンパイルされたチャンクを関数として返します。そうでない場合は、nilとエラーメッセージを返します。返された関数の環境はグローバル環境です。
chunkname
はエラーメッセージとデバッグ情報のチャンク名として使用されます。省略された場合、デフォルトは"=(load)"です。
loadfile ([filename])
load
と似ていますが、チャンクをファイルfilename
から、またはファイル名が指定されていない場合は標準入力から取得します。
loadstring (string [, chunkname])
load
に似ていますが、指定された文字列からチャンクを取得します。
指定された文字列を読み込んで実行するには、次の慣用句を使用します:
assert(loadstring(s))()
省略された場合、chunkname
は指定された文字列にデフォルト設定されます。
next (table [, index])
プログラムがテーブルの全てのフィールドをトラバースすることを可能にします。第一引数はテーブルで、第二引数はこのテーブル内のインデックスです。next
はテーブルの次のインデックスとそれに関連付けられた値を返します。第二引数にnil
を使用して呼び出された場合、next
は初期インデックスとそれに関連付けられた値を返します。最後のインデックスで呼び出された場合、または空のテーブルでnil
を使用して呼び出された場合、next
はnil
を返します。第二引数が省略された場合、それはnil
と解釈されます。特に、next(t)
を使用してテーブルが空かどうかを確認できます。
インデックスが列挙される順序は、数値インデックスであっても指定されていません。(数値順でテーブルをトラバースするには、数値のfor
またはipairs
関数を使用してください。)
トラバース中にテーブルに存在しないフィールドに値を割り当てる場合、next
の動作は未定義です。ただし、既存のフィールドを修正することはできます。特に、既存のフィールドをクリアすることができます。
pairs (t)
3つの値を返します:next
関数、テーブルt
、そしてnil
です。そのため、次の構成
for k,v in pairs(t) do body end
はテーブルt
の全てのキーと値のペアをイテレートします。
テーブルのトラバース中にテーブルを修正する際の注意点については、next
関数を参照してください。
pcall (f, arg1, ···)
関数f
を保護モードで与えられた引数で呼び出します。これは、f
内の任意のエラーが伝播されないことを意味します。代わりに、pcall
はエラーをキャッチし、ステータスコードを返します。最初の結果はステータスコード(真偽値)であり、エラーなしに呼び出しが成功するとtrue
になります。その場合、pcall
はこの最初の結果の後に、呼び出しからの全ての結果を返します。エラーが発生した場合、pcall
はfalse
とエラーメッセージを返します。
print (···)
任意の数の引数を受け取り、それらの値をtostring
関数を使用して文字列に変換し、標準出力に出力します。print
は整形された出力を意図したものではなく、通常はデバッグのために値をすばやく表示するためだけに使用されます。整形された出力にはstring.format
を使用してください。
rawequal (v1, v2)
v1
がv2
と等しいかどうかをチェックし、メタメソッドを呼び出さずに真偽値を返します。
rawget (table, index)
メタメソッドを呼び出さずにtable[index]
の実際の値を取得します。table
はテーブルでなければならず、index
は任意の値です。
rawset (table, index, value)
メタメソッドを呼び出さずにtable[index]
の実際の値をvalue
に設定します。table
はテーブルでなければならず、index
はnil
以外の任意の値であり、value
は任意のLuaの値です。 この関数はtable
を返します。
select (index, ···)
index
が数値の場合、引数index
の後のすべての引数を返します。それ以外の場合、index
は文字列"#"
でなければならず、select
は受け取った追加引数の総数を返します。
setfenv (f, table)
指定された関数に使用される環境を設定します。f
はLua関数またはスタックレベルで関数を指定する数値であり、レベル1はsetfenv
を呼び出す関数です。setfenv
は与えられた関数を返します。
特別なケースとして、f
が0の場合、setfenv
は実行中のスレッドの環境を変更します。この場合、setfenv
は値を返しません。
setmetatable (table, metatable)
指定されたテーブルのメタテーブルを設定します。(Luaから他のタイプのメタテーブルを変更することはできません。Cからのみ可能です。)metatable
がnil
の場合、指定されたテーブルのメタテーブルを削除します。元のメタテーブルに"__metatable"
フィールドがある場合、エラーが発生します。
この関数はtable
を返します。
tonumber (e [, base])
引数を数値に変換しようとします。引数が既に数値または数値に変換可能な文字列である場合、tonumber
はこの数値を返します。そうでない場合はnil
を返します。
オプションの引数は数値を解釈する基数を指定します。基数は2から36までの任意の整数です。10を超える基数では、文字'A'(大文字または小文字)が10を表し、'B'が11を表し、以降 'Z'が35を表します。10進数(デフォルト)では、数値は小数部分とオプションの指数部分を持つことができます(§2.1参照)。他の基数では、符号なし整数のみが受け入れられます。
tostring (e)
任意の型の引数を受け取り、それを合理的な形式の文字列に変換します。数値を変換する方法を完全に制御するには、string.format
を使用します。 e
のメタテーブルに"__tostring"
フィールドがある場合、tostring
はe
を引数として対応する値を呼び出し、その呼び出しの結果をその結果として使用します。
type (v)
唯一の引数の型を文字列として返します。この関数の可能な結果は "nil"
(文字列であり、値nil
ではありません)、"number"
、"string"
、"boolean"
、"table"
、"function"
、"thread"
、および "userdata"
です。
unpack (list [, i [, j]])
指定されたテーブルから要素を返します。この関数は
return list[i], list[i+1], ..., list[j]
と同等ですが、上記のコードは固定数の要素に対してのみ記述できます。デフォルトでは、i
は1で、j
は長さ演算子によって定義されたリストの長さです(§2.5.5参照)。
_VERSION
グローバル変数(関数ではない)で、現在のインタプリタのバージョンを含む文字列を保持します。この変数の現在の内容は "Lua 5.1"
です。
xpcall (f, err)
この関数はpcall
に似ていますが、新しいエラーハンドラを設定できます。
xpcall
はerr
をエラーハンドラとして使用し、保護モードで関数f
を呼び出します。f
内の任意のエラーは伝播されません。代わりに、xpcall
はエラーをキャッチし、元のエラーオブジェクトでerr
関数を呼び出し、ステータスコードを返します。最初の結果はステータスコード(真偽値)であり、エラーなしで呼び出しが成功した場合はtrueです。この場合、xpcall
はこの最初の結果の後に、呼び出しからのすべての結果も返します。エラーが発生した場合、xpcall
はfalse
とerr
からの結果を返します。
5.2 – コルーチン操作
コルーチンに関連する操作は基本ライブラリのサブライブラリであり、coroutine
テーブル内にあります。コルーチンの一般的な説明については、§2.11を参照してください。
coroutine.create (f)
本体がf
の新しいコルーチンを作成します。f
はLua関数でなければなりません。この新しいコルーチンを返します。タイプは "thread"
のオブジェクトです。
coroutine.resume (co [, val1, ...])
コルーチンco
の実行を開始または継続します。コルーチンを最初に再開するとき、その本体が実行を開始します。値val1, ...
は本体関数への引数として渡されます。コルーチンが中断されていた場合、resume
はそれを再開し、値val1, ...
はyield
からの結果として渡されます。
コルーチンがエラーなく実行されると、resume
はtrueとyield
に渡された値(コルーチンが中断した場合)または本体関数によって返された値(コルーチンが終了した場合)を返します。エラーが発生した場合、resume
はfalseとエラーメッセージを返します。
coroutine.running ()
実行中のコルーチンを返します。メインスレッドによって呼び出された場合はnilを返します。
coroutine.status (co)
コルーチンco
の状態を文字列で返します:実行中の場合は"running"(つまり、status
を呼び出した場合)、yield
への呼び出しで中断されているか、まだ実行が開始されていない場合は"suspended"、アクティブだが実行中ではない(つまり、別のコルーチンを再開した)場合は"normal"、本体関数を終了したかエラーで停止した場合は"dead"です。
coroutine.wrap (f)
本体がf
の新しいコルーチンを作成します。f
はLua関数でなければなりません。呼び出されるたびにコルーチンを再開する関数を返します。関数に渡された任意の引数は、resume
への追加の引数として機能します。resume
によって返される値と同じ値を返しますが、最初の真偽値を除きます。エラーの場合は、エラーを伝播します。
coroutine.yield (...)
呼び出し元のコルーチンの実行を中断します。コルーチンはC関数、メタメソッド、イテレータを実行中であってはなりません。yield
への任意の引数は、resume
への追加の結果として渡されます。
5.3 – モジュール
パッケージライブラリは、Luaでモジュールをロードおよび構築するための基本的な機能を提供します。その関数の2つをグローバル環境で直接エクスポートします:require
とmodule
。その他のものはテーブルpackage
でエクスポートされます。
module (name [, ...])
モジュールを作成します。package.loaded[name]
にテーブルがある場合、このテーブルがモジュールになります。そうでない場合、指定された名前のグローバルテーブルt
があれば、このテーブルがモジュールになります。そうでなければ、新しいテーブルt
を作成し、それをグローバル名とpackage.loaded[name]
の値として設定します。この関数はまた、t._NAME
を与えられた名前で、t._M
をモジュール(t
自身)で、t._PACKAGE
をパッケージ名(最後のコンポーネントを除いた完全なモジュール名)で初期化します。最後に、module
はrequire
がt
を返すように、現在の関数の新しい環境とpackage.loaded[name]
の新しい値としてt
を設定します。
名前が複合名(つまり、ドットで区切られたコンポーネントを持つもの)の場合、module
はそれぞれのコンポーネントに対してテーブルを作成(または既に存在する場合は再利用)します。例えば、名前がa.b.cであれば、module
はモジュールテーブルをグローバルaのフィールドbのフィールドcに格納します。
この関数は、モジュール名の後にオプションを受け取ることができ、各オプションはモジュールに適用される関数です。
require (modname)
指定されたモジュールをロードします。この関数はまずpackage.loaded
テーブルを調べて、modname
が既にロードされているかどうかを判断します。もしロードされている場合は、package.loaded[modname]
に格納された値をrequire
が返します。そうでない場合、モジュールのローダーを見つけるために試みます。
ローダーを見つけるために、require
はpackage.loaders
配列に従います。この配列を変更することで、require
がモジュールをどのように探すかを変更できます。以下の説明は、package.loaders
のデフォルト設定に基づいています。
最初にrequire
はpackage.preload[modname]
を問い合わせます。値があれば、この値(関数であるべきです)がローダーです。そうでなければ、require
はpackage.path
に格納されたパスを使ってLuaローダーを探します。それも失敗した場合は、package.cpath
に格納されたパスを使ってCローダーを探します。それも失敗した場合は、オールインワンローダー(package.loaders
を参照)を試みます。
ローダーが見つかったら、require
は単一の引数modname
を使用してローダーを呼び出します。ローダーが何か値を返す場合、require
はその返された値をpackage.loaded[modname]
に割り当てます。ローダーが値を返さず、package.loaded[modname]
に値を割り当てていない場合、require
はこのエントリにtrue
を割り当てます。いずれの場合も、require
はpackage.loaded[modname]
の最終値を返します。
モジュールのロードまたは実行中にエラーが発生した場合、またはモジュール用のローダーが見つからない場合、require
はエラーを通知します。
package.cpath
Cローダーを探すためにrequire
によって使用されるパスです。
Luaはpackage.cpath
を、環境変数LUA_CPATH
またはluaconf.h
で定義されたデフォルトパスを使用して、Luaパスpackage.path
と同じ方法で初期化します。
package.loaded
どのモジュールが既にロードされているかを制御するためにrequire
によって使用されるテーブルです。modname
というモジュールをrequire
して、package.loaded[modname]
がfalse
でない場合、require
は単純にそこに格納されている値を返します。
package.loaders
モジュールのロード方法を制御するためにrequire
によって使用されるテーブルです。
このテーブルの各エントリはサーチャー関数です。モジュールを探す際に、require
はこれらのサーチャーを昇順で呼び出し、モジュール名(require
に与えられた引数)をその唯一のパラメータとして使用します。関数は別の関数(モジュールローダー)またはそのモジュールが見つからなかった理由を説明する文字列(または何も言うことがない場合はnil
)を返すことができます。Luaはこのテーブルを4つの関数で初期化します。
最初のサーチャーは単にpackage.preload
テーブル内のローダーを探します。
2番目のサーチャーは、package.path
に格納されているパスを使用してLuaライブラリとしてローダーを探します。パスはセミコロンで区切られたテンプレートのシーケンスです。各テンプレートについて、サーチャーはテンプレート内の各疑問符をファイル名に置き換えます。ファイル名はモジュール名で、各ドットは「ディレクトリセパレータ」(Unixでは"/"など)に置き換えられます。その後、結果のファイル名を開こうと試みます。例えば、Luaパスが文字列
"./?.lua;./?.lc;/usr/local/?/init.lua"
であれば、モジュールfoo
のLuaファイルを探す際には、./foo.lua
、./foo.lc
、/usr/local/foo/init.lua
の順にファイルを開こうとします。
3番目のサーチャーは、変数package.cpath
によって与えられたパスを使用してCライブラリとしてローダーを探します。例えば、Cパスが文字列
"./?.so;./?.dll;/usr/local/?/init.so"
であれば、モジュールfoo
のサーチャーは./foo.so
、./foo.dll
、/usr/local/foo/init.so
の順にファイルを開こうと試みます。Cライブラリを見つけたら、このサーチャーはまず動的リンク機能を使用してアプリケーションをライブラリにリンクします。その後、ライブラリ内のC関数をローダーとして使用するために探します。このC関数の名前は、"luaopen_"とモジュール名の各ドットがアンダースコアに置き換えられたコピーとを連結した文字列です。さらに、モジュール名にハイフンがある場合は、最初のハイフンまで(ハイフンを含む)のプレフィックスが削除されます。例えば、モジュール名がa.v1-b.c
であれば、関数名はluaopen_b_c
になります。
4番目のサーチャーはオールインワンローダーを試みます。指定されたモジュールのルート名に対するCライブラリをCパスで探します。例えば、a.b.c
を要求するとき、a
に対するCライブラリを探します。見つかった場合、サブモジュールのオープン関数を探します。例の場合、それはluaopen_a_b_c
になります。この機能により、パッケージは複数のCサブモジュールを1つのライブラリにパックでき、各サブモジュールは元のオープン関数を保持できます。
package.loadlib (libname, funcname)
ホストプログラムをCライブラリlibname
に動的にリンクします。このライブラリ内で、関数funcname
を探し、この関数をC関数として返します。(したがって、funcname
はプロトコル(lua_CFunction
を参照)に従う必要があります)。
これは低レベルの関数です。パッケージとモジュールシステムを完全に迂回します。require
とは異なり、パス検索を実行せず、自動的に拡張子を追加しません。libname
は必要に応じてパスと拡張子を含むCライブラリの完全なファイル名でなければなりません。funcname
はCライブラリによってエクスポートされた正確な名前でなければなりません(これは使用されるCコンパイラとリンカーに依存するかもしれません)。
この関数はANSI Cによってサポートされていません。そのため、一部のプラットフォーム(Windows、Linux、Mac OS X、Solaris、BSD、およびdlfcn標準をサポートするその他のUnixシステム)でのみ利用可能です。
package.path
Luaローダーを検索するためにrequire
が使用するパスです。
起動時に、Luaはこの変数を環境変数LUA_PATH
の値で初期化するか、環境変数が定義されていない場合はluaconf.h
で定義されたデフォルトパスで初期化します。環境変数の値にある任意の";;"はデフォルトパスに置き換えられます。
package.preload
特定のモジュールのローダーを格納するためのテーブルです(require
を参照)。
package.seeall (module)
module
のメタテーブルを設定し、その__index
フィールドがグローバル環境を参照するようにします。これにより、このモジュールはグローバル環境から値を継承します。関数module
へのオプションとして使用されます。
5.4 – 文字列操作
このライブラリは、文字列の検索や抽出、パターンマッチングなどの文字列操作のための汎用関数を提供します。Luaで文字列をインデックス付けするとき、最初の文字は位置1にあります(Cのように0ではありません)。インデックスには負の値を使用でき、文字列の末尾から逆にインデックス付けされると解釈されます。したがって、最後の文字は位置-1にあり、以降同様です。
文字列ライブラリはそのすべての関数をstring
テーブル内に提供します。また、文字列のメタテーブルを設定し、__index
フィールドが文字列テーブルを指すようにします。そのため、オブジェクト指向スタイルで文字列関数を使用することができます。例えば、string.byte(s, i)
はs:byte(i)
と書くことができます。
文字列ライブラリは1バイト文字エンコーディングを前提としています。
string.byte (s [, i [, j]])
文字 s[i]
、s[i+1]
、...、s[j]
の内部数値コードを返します。i
のデフォルト値は1で、j
のデフォルト値はi
です。
数値コードはプラットフォーム間で必ずしも移植可能ではないことに注意してください。
string.char (···)
0個以上の整数を受け取ります。各文字が対応する引数と等しい内部数値コードを持つ、引数の数に等しい長さの文字列を返します。 数値コードはプラットフォーム間で必ずしも移植可能ではないことに注意してください。
string.dump (function)
指定された関数のバイナリ表現を含む文字列を返し、後でこの文字列に対してloadstring
を行うと、関数のコピーが返されます。関数はアップバリューを持たないLua関数でなければなりません。
string.find (s, pattern [, init [, plain]])
文字列s
でパターンに最初にマッチするものを探します。マッチが見つかった場合、findはこの出現が開始されるs
のインデックスと終了するインデックスを返します。それ以外の場合はnilを返します。3番目のオプションの数値引数init
は検索を開始する場所を指定し、デフォルト値は1で負の値も可能です。4番目のオプション引数plain
にtrueが与えられると、パターンマッチング機能がオフになり、関数はパターン内の文字を「魔法」とみなさない普通の「部分文字列を見つける」操作を行います。plain
が指定された場合は、init
も指定されている必要があります。
パターンにキャプチャがある場合、成功したマッチでは、2つのインデックスの後に、キャプチャされた値も返されます。
string.format (formatstring, ···)
変数の数に応じた引数を、最初の引数(文字列である必要があります)で与えられた説明に従ってフォーマットされたバージョンで返します。フォーマット文字列は、標準C関数のprintfファミリーと同じルールに従います。唯一の違いは、オプション/修飾子*
、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
は文字列を期待しています。
この関数は、q
オプションへの引数としての場合を除き、組み込みゼロを含む文字列値を受け入れません。
string.gmatch (s, pattern)
呼び出すたびに、文字列s
上でパターンから次のキャプチャを返すイテレータ関数を返します。パターンがキャプチャを指定していない場合、各呼び出しで完全なマッチが生成されます。 例として、以下のループ
s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do
print(w)
end
は、文字列s
からのすべての単語を繰り返し、一行に一つずつ印刷します。次の例は、与えられた文字列からすべてのキー=値のペアをテーブルに収集します:
t = {}
s = "from=world, to=Lua"
for k, v in string.gmatch(s, "(%w+)=(%w+)") do
t[k] = v
end
この関数では、パターンの先頭の^
はアンカーとして機能しません。これは反復を妨げるためです。
string.gsub (s, pattern, repl [, n])
s
のコピーを返し、すべての(または与えられた場合は最初のn
個の)パターンの出現をrepl
によって指定された置換文字列に置き換えます。repl
は文字列、テーブル、または関数である可能性があります。gsub
はまた、その2番目の値として、発生した総マッチ数を返します。
repl
が文字列の場合、その値が置換に使用されます。文字%
はエスケープ文字として機能します:repl
内の%n
という形式の任意のシーケンスは、n
が1から9の間の場合、n
番目のキャプチャされた部分文字列の値を表します(下記参照)。シーケンス%0
は全体のマッチを表します。シーケンス%%
は単一の%
を表します。
repl
がテーブルの場合、テーブルはすべてのマッチごとに、最初のキャプチャをキーとして照会されます。パターンがキャプチャを指定していない場合、全体のマッチがキーとして使用されます。
repl
が関数の場合、この関数はマッチが発生するたびに呼び出され、すべてのキャプチャされた部分文字列が順番に引数として渡されます。パターンがキャプチャを指定していない場合、全体のマッチが唯一の引数として渡されます。
テーブルの照会または関数呼び出しによって返される値が文字列または数値の場合、それは置換文字列として使用されます。それ以外の場合、もし値がfalseまたはnilであれば、置換は行われません(つまり、元のマッチが文字列に保持されます)。
いくつかの例を挙げます:
x = string.gsub("hello world", "(%w+)", "%1 %1")
--> x="hello hello world world"
x = string.gsub("hello world", "%w+", "%0 %0", 1)
--> x="hello hello world"
x = string.gsub("hello world from Lua", "(%w+)%s*(%w+)", "%2 %1")
--> x="world hello Lua from"
x = string.gsub("home = $HOME, user = $USER", "%$(%w+)", os.getenv)
--> x="home = /home/roberto, user = roberto"
x = string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s)
return loadstring(s)()
end)
--> x="4+5 = 9"
local t = {name="lua", version="5.1"}
x = string.gsub("$name-$version.tar.gz", "%$(%w+)", t)
--> x="lua-5.1.tar.gz"
string.len (s)
文字列を受け取り、その長さを返します。空文字列""
の長さは0です。組み込みのゼロはカウントされるので、"a\000bc\000"は長さが5です。
string.lower (s)
文字列を受け取り、すべての大文字を小文字に変換したこの文字列のコピーを返します。他の文字は変更されません。大文字とは何かの定義は現在のロケールに依存します。
string.match (s, pattern [, init])
文字列s
でパターンに最初にマッチするものを探します。もし見つかれば、matchはパターンからキャプチャを返し、そうでなければnilを返します。パターンがキャプチャを指定していない場合は、全体のマッチが返されます。3番目のオプションの数値引数initは検索を開始する場所を指定し、デフォルト値は1で、負の値も取ることができます。
string.rep (s, n)
文字列s
のn
コピーの連結である文字列を返します。
string.reverse (s)
文字列s
を反転させた文字列を返します。
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)
文字列を受け取り、すべての小文字を大文字に変換したこの文字列のコピーを返します。他の文字は変更されません。小文字とは何かの定義は現在のロケールに依存します。
5.4.1 – パターン
文字クラス:
文字クラスは、文字のセットを表すために使用されます。文字クラスを記述するために許可される以下の組み合わせがあります:
x
: (xがマジック文字^$()%.[]*+-?
のいずれでもない場合)は文字x
自体を表します。.
: (ドット)はすべての文字を表します。%a
: すべての文字を表します。%c
: すべての制御文字を表します。%d
: すべての数字を表します。%l
: すべての小文字を表します。%p
: すべての句読点文字を表します。%s
: すべての空白文字を表します。%u
: すべての大文字を表します。%w
: すべての英数字を表します。%x
: すべての16進数の数字を表します。%z
: 表現0の文字を表します。%x
: (x
が英数字でない任意の文字の場合)は文字xを表します。これはマジック文字をエスケープする標準的な方法です。パターンで自体を表すために使用されるとき、任意の句読点文字(マジックでないものも含む)は%
で前置できます。[set]
:set
内のすべての文字の和集合を表すクラスです。文字の範囲は、範囲の終端文字を-
で区切ることによって指定できます。上記で説明されたすべてのクラス%x
もset
の要素として使用できます。set
内の他のすべての文字はそれ自体を表します。例えば、[%w_]
(または[_%w]
)はすべての英数字とアンダースコアを表し、[0-7]
は8進数の数字を表し、[0-7%l%-]
は8進数の数字と小文字の文字と-
文字を表します。
範囲とクラスの間の相互作用は定義されていません。したがって、[%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は異なる2つの文字)は、xで始まり、yで終わる文字列で、xとyがバランスを取っているものに一致します。これは、文字列を左から右に読んでいき、xに対して+1、yに対して-1を数えると、カウントが0になる最初のyが終了yであることを意味します。例えば、アイテム%b()
はバランスの取れた括弧の式に一致します。
パターン:
パターンはパターンアイテムのシーケンスです。パターンの先頭の^
は、対象文字列の始まりにマッチをアンカーします。パターンの末尾の$
は、対象文字列の終わりにマッチをアンカーします。他の位置では、^
と$
に特別な意味はなく、それ自体を表します。
キャプチャ:
パターンには括弧で囲まれたサブパターンを含めることができ、これらはキャプチャを記述します。マッチが成功すると、対象文字列のキャプチャに一致する部分文字列が保存(キャプチャ)され、将来的に使用されます。キャプチャは左括弧によって番号付けされます。例えば、パターン"(a*(.)%w(%s*))"の場合、文字列の"a*(.)%w(%s*)"に一致する部分が最初のキャプチャとして保存され(したがって番号1になります)、"."に一致する文字が番号2でキャプチャされ、"%s*"に一致する部分が番号3になります。
特別なケースとして、空のキャプチャ()は現在の文字列位置(数値)をキャプチャします。例えば、文字列"flaaap"にパターン"()aa()"を適用すると、2つのキャプチャが得られます:3と5。
パターンに埋め込まれたゼロを含めることはできません。代わりに%zを使用してください。
5.5 – テーブル操作
このライブラリはテーブル操作のための汎用関数を提供します。これらの関数はすべてtable
テーブル内にあります。
テーブルライブラリのほとんどの関数は、テーブルが配列またはリストを表していると仮定しています。これらの関数において、テーブルの「長さ」とは、長さオペレーターの結果を意味します。
table.concat (table [, sep [, i [, j]]])
すべての要素が文字列または数値である配列に対して、table[i]..sep..table[i+1] ··· sep..table[j]
を返します。sep
のデフォルト値は空文字列、i
のデフォルトは1、j
のデフォルトはテーブルの長さです。i
がj
より大きい場合、空文字列を返します。
table.insert (table, [pos,] value)
必要に応じて他の要素を上にシフトして空間を開けることで、テーブル内の位置pos
に要素value
を挿入します。pos
のデフォルト値はn+1です。ここでnはテーブルの長さです(§2.5.5を参照)。したがって、table.insert(t,x)
の呼び出しは、テーブルt
の末尾にx
を挿入します。
table.maxn (table)
与えられたテーブルの最大の正の数値インデックスを返します。テーブルに正の数値インデックスがない場合はゼロを返します。(この関数が機能するためには、テーブル全体を線形にトラバースします。)
table.remove (table [, pos])
テーブルからpos
位置にある要素を削除し、必要に応じて他の要素を下にシフトして空間を詰めます。削除された要素の値を返します。pos
のデフォルト値はnで、nはテーブルの長さです。したがって、table.remove(t)
の呼び出しはテーブルt
の最後の要素を削除します。
table.sort (table [, comp])
指定された順序でテーブルの要素を、テーブル[1]からテーブル[n]までの場所に、その場でソートします。ここでnはテーブルの長さです。comp
が与えられた場合、それは2つのテーブル要素を受け取り、最初の要素が2番目の要素より小さいときにtrueを返す関数でなければなりません(ソート後にnot comp(a[i+1],a[i])
がtrueになるように)。comp
が与えられていない場合、代わりに標準のLua演算子<が使用されます。 ソートアルゴリズムは安定していません。つまり、与えられた順序で等しいと見なされる要素は、ソートによって相対位置が変わる可能性があります。
5.6 – 数学関数
このライブラリは標準C数学ライブラリへのインターフェースです。すべての関数をmath
テーブル内に提供します。
math.abs (x)
xの絶対値を返します。
math.acos (x)
xの逆余弦(ラジアン単位)を返します。
math.asin (x)
xの逆正弦(ラジアン単位)を返します。
math.atan (x)
xの逆正接(ラジアン単位)を返します。
math.atan2 (y, x)
y/xの逆正接(ラジアン単位)を返しますが、結果の象限を見つけるために両方のパラメータの符号を使用します。(xがゼロの場合も正しく扱います。)
math.ceil (x)
x以上の最小の整数を返します。
math.cos (x)
xのコサイン(ラジアン単位と仮定)を返します。
math.cosh (x)
xの双曲線コサインを返します。
math.deg (x)
ラジアン単位で与えられた角度xを度単位で返します。
math.exp (x)
e^xの値を返します。
math.floor (x)
x以下の最大の整数を返します。
math.fmod (x, y)
xをyで割った余りを返しますが、商をゼロに向かって丸めます。
math.frexp (x)
x = m2^eとなるmとeを返します。ここで、eは整数であり、mの絶対値は[0.5, 1]
の範囲にあります(xがゼロの場合はゼロです)。
math.huge
HUGE_VALの値で、他のどの数値よりも大きいか同じ値です。
math.ldexp (m, e)
m2^eを返します(eは整数である必要があります)。
math.log (x)
xの自然対数を返します。
math.log10 (x)
xの底が10の対数を返します。
math.max (x, ···)
引数の中で最大の値を返します。
math.min (x, ···)
引数の中で最小の値を返します。
math.modf (x)
xの整数部と小数部の2つの数値を返します。
math.pi
π(パイ)の値です。
math.pow (x, y)
x^yを返します。(この値は式x^yを使っても計算できます。)
math.rad (x)
度単位で与えられた角度xをラジアンで返します。
math.random ([m [, n]])
この関数はANSI Cによって提供される簡単な擬似乱数生成関数randへのインターフェースです。(その統計的性質については保証がありません。)
引数なしで呼び出された場合、[0,1]
の範囲で一様な擬似乱数実数を返します。整数mを引数として呼び出された場合、math.random
は[1, m]
の範囲で一様な擬似乱数整数を返します。2つの整数mとnを引数として呼び出された場合、math.random
は[m, n]
の範囲で一様な擬似乱数整数を返します。
math.randomseed (x)
擬似乱数生成器の「シード」としてxを設定します:等しいシードは等しい数値のシーケンスを生成します。
math.sin (x)
xの正弦を返します(ラジアン単位と仮定)。
math.sinh (x)
xの双曲線正弦を返します。
math.sqrt (x)
xの平方根を返します。(この値は式x^0.5
を使っても計算できます。)
math.tan (x)
xの正接を返します(ラジアン単位と仮定)。
math.tanh (x)
xの双曲線正接を返します。
5.7 – 入出力機能
入出力ライブラリは、ファイル操作のために2つの異なるスタイルを提供します。1つ目は暗黙のファイルディスクリプタを使用します。つまり、デフォルトの入力ファイルとデフォルトの出力ファイルを設定する操作があり、すべての入出力操作はこれらのデフォルトファイル上で行われます。2つ目のスタイルでは、明示的なファイルディスクリプタを使用します。
暗黙のファイルディスクリプタを使用する場合、すべての操作はio
テーブルによって提供されます。明示的なファイルディスクリプタを使用する場合、io.open
操作はファイルディスクリプタを返し、その後のすべての操作はファイルディスクリプタのメソッドとして提供されます。
io
テーブルは、C言語の標準的な意味で3つの事前定義されたファイルディスクリプタも提供します:io.stdin
、io.stdout
、io.stderr
。入出力ライブラリはこれらのファイルを決して閉じません。
特に明記されていない限り、すべての入出力関数は失敗時にはnilを返し(2番目の結果としてエラーメッセージ、3番目の結果としてシステム依存のエラーコードも返します)、成功時にはnilではない何かの値を返します。
io.close ([file])
file:close()
と同等です。ファイルが指定されていない場合、デフォルトの出力ファイルを閉じます。
io.flush ()
デフォルトの出力ファイルに対してfile:flush
と同等です。
io.input ([file])
ファイル名が指定された場合、指定されたファイルをテキストモードで開き、そのハンドルをデフォルトの入力ファイルとして設定します。ファイルハンドルが指定された場合、単にこのファイルハンドルをデフォルトの入力ファイルとして設定します。パラメータなしで呼び出された場合、現在のデフォルト入力ファイルを返します。
エラーが発生した場合、この関数はエラーコードを返す代わりにエラーを発生させます。
io.lines ([filename])
指定されたファイル名を読み取りモードで開き、それを呼び出すたびにファイルから新しい行を返すイテレータ関数を返します。したがって、
for line in io.lines(filename) do body end
の構造は、ファイルのすべての行に対して繰り返します。イテレータ関数がファイルの終わりを検出すると、nilを返して(ループを終了させる)自動的にファイルを閉じます。
ファイル名なしでio.lines()
(を呼び出すと、io.input():lines()
と同等です。つまり、デフォルト入力ファイルの行を反復処理します。この場合、ループが終了してもファイルは閉じません。
io.open (filename [, mode])
指定されたモードでファイルを開く関数です。新しいファイルハンドルを返すか、エラーが発生した場合はnilとエラーメッセージを返します。
モード文字列には以下のものが使用できます:
- "r": 読み取りモード(デフォルト);
- "w": 書き込みモード;
- "a": 追記モード;
- "r+": 更新モード、以前のデータは保持されます;
- "w+": 更新モード、以前のデータは消去されます;
- "a+": 追記更新モード、以前のデータは保持され、ファイルの最後にのみ書き込みが許可されます。
モード文字列には、いくつかのシステムでファイルをバイナリモードで開くために必要な'b'が末尾に付けられることもあります。この文字列は、標準C関数fopenで使用されるものと全く同じです。
io.output ([file])
io.input
に似ていますが、デフォルトの出力ファイルに対して操作を行います。
io.popen (prog [, mode])
プログラムprog
を別プロセスで開始し、このプログラムからデータを読み取るため(モードが"r"の場合、デフォルト)またはこのプログラムにデータを書き込むために使用できるファイルハンドルを返します(モードが"w"の場合)。
この関数はシステム依存であり、すべてのプラットフォームで利用可能なわけではありません。
io.read (···)
io.input():read
と同等です。
io.tmpfile ()
一時ファイル用のハンドルを返します。このファイルは更新モードで開かれ、プログラムが終了すると自動的に削除されます。
io.type (obj)
obj
が有効なファイルハンドルかどうかをチェックします。obj
が開いているファイルハンドルであれば"file"、閉じているファイルハンドルであれば"closed file"を返し、ファイルハンドルでなければnilを返します。
io.write (···)
io.output():write
と同等です。
file:close ()
ファイルを閉じます。ファイルハンドルがガベージコレクションによって自動的に閉じられることに注意してくださいが、そのタイミングは予測不可能です。
file:flush ()
書き込まれたデータをファイルに保存します。
file:lines ()
ファイルから新しい行を返すイテレータ関数を返します。したがって、次の構文
for line in file:lines() do body end
は、ファイルのすべての行を反復処理します。(io.lines
とは異なり、この関数はループの終了時にファイルを閉じません。)
file:read (···)
指定されたフォーマットに従ってファイルを読み込みます。各フォーマットに対して、関数は読み込まれた文字列(または数値)を返すか、指定されたフォーマットでデータを読み込めない場合はnilを返します。フォーマットが指定されていない場合は、次の行全体を読み込むデフォルトのフォーマットを使用します(下記参照)。
利用可能なフォーマットは以下の通りです。
- "*n": 数値を読み込みます。これは文字列ではなく数値を返す唯一のフォーマットです。
- "*a": 現在の位置からファイル全体を読み込みます。ファイルの終わりに到達した場合は、空文字列を返します。
- "*l": 次の行を読み込みます(行末をスキップ)。ファイルの終わりに達した場合はnilを返します。これがデフォルトのフォーマットです。
- 数値: この数値までの文字数の文字列を読み込みます。ファイルの終わりに達した場合はnilを返します。数値が0の場合は何も読み込まず、空文字列を返すか、ファイルの終わりに達した場合はnilを返します。
file:seek ([whence] [, offset])
ファイル位置を設定し、取得します。これは、文字列whence
で指定された基準からオフセットプラス位置で測定されます。
- "set": 基準は位置0(ファイルの始まり)です。
- "cur": 基準は現在の位置です。
- "end": 基準はファイルの終わりです。
成功した場合、seek
関数はファイルの始まりから測った最終ファイル位置をバイト単位で返します。この関数が失敗した場合は、nilとエラーを説明する文字列を返します。
whence
のデフォルト値は"cur"で、offset
のデフォルト値は0です。したがって、file:seek()
呼び出しは現在のファイル位置を変更せずに返し、file:seek("set")
呼び出しは位置をファイルの始まりに設定し(0を返します)、file:seek("end")
呼び出しは位置をファイルの終わりに設定し、そのサイズを返します。
file:setvbuf (mode [, size])
出力ファイルのバッファリングモードを設定します。利用可能なモードは3つあります:
- "no": バッファリングなし。任意の出力操作の結果は即座に表示されます。
- "full": 完全なバッファリング。出力操作はバッファが満杯になった時(またはファイルを明示的にフラッシュした時(
io.flush
参照))のみ行われます。 - "line": 行バッファリング。出力は改行が出力されるか、ある特別なファイル(端末デバイスなど)からの入力があるまでバッファされます。
後者2つの場合、sizeはバッファのサイズをバイト単位で指定します。デフォルトは適切なサイズです。
file:write (···)
その引数の各値をファイルに書き込みます。引数は文字列または数値でなければなりません。他の値を書き込むには、write
の前にtostring
またはstring.format
を使用します。
5.8 – オペレーティングシステムの機能
このライブラリはos
テーブルを通じて実装されます。
os.clock ()
プログラムによって使用されたCPU時間の秒数の近似値を返します。
os.date ([format [, time]])
指定された文字列フォーマットに従ってフォーマットされた日付と時刻を含む文字列またはテーブルを返します。
time引数が存在する場合、これはフォーマットされる時刻です(この値の説明についてはos.time
関数を参照してください)。そうでない場合、date
は現在の時刻をフォーマットします。
フォーマットが'!'で始まる場合、日付は協定世界時でフォーマットされます。このオプション文字の後、フォーマットが文字列"*t"の場合、date
は次のフィールドを持つテーブルを返します:year(4桁の数字)、month(1-12)、day(1-31)、hour(0-23)、min(0-59)、sec(0-61)、wday(曜日、日曜日は1)、yday(年内の日数)、およびisdst(夏時間フラグ、ブール値)。
フォーマットが"*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
をオペレーティングシステムのシェルに実行させます。システム依存のステータスコードを返します。command
が省略された場合、シェルが利用可能なら非ゼロを、そうでなければゼロを返します。
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", または "time";デフォルトカテゴリは"all"です。この関数は新しいロケールの名前を返すか、リクエストが承認されない場合はnilを返します。
locale
が空文字列の場合、現在のロケールは実装定義のネイティブロケールに設定されます。locale
が文字列"C"の場合、現在のロケールは標準Cロケールに設定されます。
最初の引数にnilを指定して呼び出すと、この関数は指定したカテゴリの現在のロケールの名前のみを返します。
os.time ([table])
引数なしで呼び出された場合は現在の時刻を返し、与えられたテーブルによって指定された日付と時刻を表す時刻を返します。このテーブルにはyear
、month
、day
のフィールドが必要で、hour
、min
、sec
、isdst
のフィールドがある場合があります(これらのフィールドの説明については、os.date
関数を参照してください)。
返される値は数値であり、その意味はシステムに依存します。POSIX、Windows、およびその他のいくつかのシステムでは、この数は特定の開始時刻("epoch")からの秒数を数えます。他のシステムでは、意味は指定されておらず、time
によって返される数値はdate
およびdifftime
への引数としてのみ使用できます。
os.tmpname ()
一時ファイルに使用できるファイル名を持つ文字列を返します。このファイルは使用前に明示的に開かれ、不要になったら明示的に削除される必要があります。
一部のシステム(POSIX)では、この関数はその名前のファイルを作成して、セキュリティリスクを回避します(名前の取得とファイルの作成の間に、誰かが間違った権限でファイルを作成する可能性があります)。ファイルを使用し、削除するには(使用しない場合でも)、ファイルを開く必要があります。
可能であれば、プログラムの終了時に自動的にファイルを削除するio.tmpfile
を使用することをお勧めします。
5.9 – デバッグライブラリ
このライブラリは、Luaプログラムにデバッグインターフェイスの機能を提供します。このライブラリを使用する際には注意を払う必要があります。ここで提供される関数は、デバッグやプロファイリングなどのタスク専用に使用されるべきです。通常のプログラミングツールとしてこれらを使用する誘惑に抵抗してください:これらは非常に遅くなる可能性があります。さらに、これらの関数のいくつかはLuaコードに関するいくつかの前提(例えば、関数にローカルな変数に外部からアクセスできない、またはLuaコードによってユーザーデータのメタテーブルを変更できない)を破るため、それ以外は安全なコードを危険にさらす可能性があります。
このライブラリのすべての関数はdebug
テーブル内に提供されます。スレッドに操作を行うすべての関数には、操作するスレッドを指定するオプションの最初の引数があります。デフォルトは常に現在のスレッドです。
debug.debug ()
ユーザーとの対話モードに入り、ユーザーが入力する各文字列を実行します。シンプルなコマンドやその他のデバッグ機能を使用して、ユーザーはグローバル変数やローカル変数を調べたり、その値を変更したり、式を評価したりすることができます。単語 cont
のみを含む行はこの関数を終了させ、呼び出し元の実行が続行されます。
debug.debug
のコマンドは、任意の関数内に文法的にネストされていないため、ローカル変数に直接アクセスすることはできないことに注意してください。
debug.getfenv (o)
オブジェクト o
の環境を返します。
debug.gethook ([thread])
スレッドの現在のフック設定を、現在のフック関数、現在のフックマスク、現在のフックカウント(debug.sethook
関数によって設定される)の3つの値として返します。
debug.getinfo ([thread,] function [, what])
関数に関する情報を含むテーブルを返します。関数を直接指定するか、または関数の値として数値を指定して、指定されたスレッドのコールスタックのレベル function
で実行されている関数を意味することができます:レベル0は現在の関数(getinfo
自体)です;レベル1は getinfo
を呼び出した関数です;以降同様です。function
がアクティブな関数の数より大きい数値の場合、getinfo
は nil
を返します。
返されるテーブルには、lua_getinfo
によって返されるすべてのフィールドが含まれることがあり、文字列 what
はどのフィールドを埋めるかを記述します。what
のデフォルトは、有効な行のテーブルを除く、利用可能なすべての情報を取得することです。オプション 'f' が存在する場合、関数自体を含む func
という名前のフィールドが追加されます。オプション 'L' が存在する場合、有効な行のテーブルを含む activelines
という名前のフィールドが追加されます。
例えば、式 debug.getinfo(1,"n").name
は、合理的な名前が見つかる場合、現在の関数の名前を持つテーブルを返し、式 debug.getinfo(print)
は print
関数に関するすべての利用可能な情報を含むテーブルを返します。
debug.getlocal ([thread,] level, local)
この関数は、スタックのレベル level
にある関数のインデックス local
にあるローカル変数の名前と値を返します。(最初のパラメータまたはローカル変数のインデックスは1であり、最後のアクティブなローカル変数まで続きます。)指定されたインデックスのローカル変数がない場合は nil
を返し、範囲外のレベルで呼び出された場合はエラーを発生させます。(レベルが有効かどうかを確認するには debug.getinfo
を呼び出すことができます。)
'(
'(開き括弧)で始まる変数名は、内部変数(ループ制御変数、一時変数、C関数のローカル変数)を表します。
debug.getmetatable (object)
指定されたオブジェクトのメタテーブルを返します。メタテーブルがない場合は nil
を返します。
debug.getregistry ()
レジストリテーブルを返します(§3.5参照)。
debug.getupvalue (func, up)
関数 func
のアップバリューのインデックス up
の名前と値を返します。指定されたインデックスのアップバリューがない場合は nil
を返します。
debug.setfenv (object, table)
指定されたオブジェクトの環境を指定されたテーブルに設定します。オブジェクトを返します。
debug.sethook ([thread,] hook, mask [, count])
指定された関数をフックとして設定します。文字列 mask
と数値 count
は、フックがいつ呼び出されるかを記述します。文字列 mask
には以下の文字が含まれ、指定された意味を持ちます:
- "c": Luaが関数を呼び出すたびにフックが呼び出されます。
- "r": Luaが関数から戻るたびにフックが呼び出されます。
- "l": Luaが新しいコード行に入るたびにフックが呼び出されます。
count
がゼロでない場合、フックは count
命令ごとに呼び出されます。
引数なしで呼び出された場合、debug.sethook
はフックをオフにします。
フックが呼び出されると、その最初の引数はフックの呼び出しを引き起こしたイベントを記述する文字列です: "call"、"return"(tail callからのリターンをシミュレートする場合は "tail return")、"line"、"count"。lineイベントの場合、フックは新しい行番号を第二引数として受け取ります。フック内では、実行中の関数についての詳細情報を得るためにレベル2でgetinfo
を呼び出すことができます(レベル0はgetinfo
関数、レベル1はフック関数です)、ただしイベントが "tail return" の場合を除きます。この場合、Luaはリターンをシミュレートしているだけであり、getinfo
への呼び出しは無効なデータを返します。
debug.setlocal ([thread,] level, local, value)
この関数は、スタックのレベルlevel
にある関数のインデックスlocal
のローカル変数に値value
を割り当てます。指定されたインデックスのローカル変数がない場合はnil
を返し、範囲外のレベルで呼び出された場合はエラーを発生させます。(レベルが有効かどうかを確認するにはgetinfo
を呼び出すことができます。)それ以外の場合は、ローカル変数の名前を返します。
debug.setmetatable (object, table)
指定されたオブジェクトのメタテーブルを指定されたテーブル(nil
も可能)に設定します。
debug.setupvalue (func, up, value)
この関数は、関数func
のアップバリューのインデックスup
に値value
を割り当てます。指定されたインデックスのアップバリューがない場合はnil
を返します。それ以外の場合は、アップバリューの名前を返します。
debug.traceback ([thread,] [message [, level]])
コールスタックのトレースバックの文字列を返します。オプションのメッセージ文字列はトレースバックの始まりに追加されます。オプションのレベル番号はトレースバックを開始するレベルを指定します(デフォルトは1、トレースバックを呼び出す関数)。
6 – Lua スタンドアロン
Luaは拡張言語として設計され、ホストCプログラムに組み込まれることを意図していますが、スタンドアロン言語としても頻繁に使用されます。スタンドアロン言語としてのLuaのインタプリタは、単にluaと呼ばれ、標準配布に含まれています。スタンドアロンインタプリタには、デバッグライブラリを含むすべての標準ライブラリが含まれています。その使用方法は以下の通りです:
lua [options] [script [args]]
オプションは以下の通りです:
-e stat
: 文字列stat
を実行します。-l mod
:mod
を"require"します。-i
: スクリプトの実行後に対話モードに入ります。-v
: バージョン情報を表示します。--
: オプションの処理を停止します。-
: 標準入力をファイルとして実行し、オプションの処理を停止します。
オプションを処理した後、luaは指定されたスクリプトを実行し、指定されたargsを文字列引数として渡します。引数なしで呼び出された場合、luaは標準入力(stdin)が端末の場合はlua -v -i
として、そうでない場合はlua -
として振る舞います。
任意の引数を実行する前に、インタプリタは環境変数LUA_INIT
をチェックします。その形式が@filename
であれば、luaはそのファイルを実行します。そうでなければ、luaは文字列自体を実行します。
すべてのオプションは-i
を除いて順番に処理されます。例えば、
lua -e'a=1' -e 'print(a)' script.lua
この呼び出しでは、最初にaを1に設定し、次にaの値('1')を表示し、最後に引数なしでファイルscript.lua
を実行します。(ここで$
はシェルプロンプトです。プロンプトは異なる場合があります。)
スクリプトの実行を開始する前に、luaはコマンドラインのすべての引数をarg
というグローバルテーブルに収集します。スクリプト名はインデックス0に格納され、スクリプト名の後の最初の引数はインデックス1に格納され、以下同様に続きます。スクリプト名の前の任意の引数(つまり、インタプリタ名とオプション)は負のインデックスに格納されます。例えば、呼び出し
lua -la b.lua t1 t2
では、インタプリタは最初にファイルa.lua
を実行し、次にテーブル
arg = { [-2] = "lua", [-1] = "-la",
[0] = "b.lua",
[1] = "t1", [2] = "t2" }
を作成し、最後にファイルb.lua
を実行します。スクリプトは引数arg[1]
、arg[2]
、...で呼び出されます。また、可変長引数式...
を使用してこれらの引数にアクセスすることも
対話モードでは、不完全な文を入力すると、インタープリタは異なるプロンプトを表示してその完了を待ちます。
グローバル変数_PROMPT
が文字列を含む場合、その値がプロンプトとして使用されます。同様に、グローバル変数_PROMPT2
が文字列を含む場合、その値が不完全な文の際に表示されるセカンダリプロンプトとして使用されます。したがって、これらのプロンプトはコマンドラインやLuaプログラム内で_PROMPT
に割り当てることによって直接変更できます。次の例を参照してください:
lua -e"_PROMPT='myprompt> '" -i
(外側の引用符はシェル用、内側の引用符はLua用です。)対話モードに入るための-i
の使用に注意してください。さもなければ、プログラムは_PROMPT
への割り当ての直後に静かに終了します。
UnixシステムでLuaをスクリプトインタプリタとして使用できるようにするため、スタンドアロンインタープリタは、チャンクの最初の行が#
で始まる場合、その行をスキップします。したがって、Luaスクリプトはchmod +x
と#!
形式を使用して実行可能プログラムにすることができます:
#!/usr/local/bin/lua
(もちろん、Luaインタープリタの場所はマシンによって異なる場合があります。luaがPATH内にある場合、
#!/usr/bin/env lua
はより移植性の高い解決策です。)
7 – 以前のバージョンとの非互換性
ここでは、Lua 5.0からLua 5.1にプログラムを移行するときに見つかる可能性のある非互換性をリストします。適切なオプションでLuaをコンパイルすることで、ほとんどの非互換性を回避できます(luaconf.
hファイルを参照)。しかし、これらの互換性オプションは、Luaの次のバージョンでは削除されます。
7.1 – 言語の変更点
- 可変長引数システムが、追加引数を含むテーブルを持つ疑似引数
arg
から、可変長引数式へと変更されました。(luaconf.h
のコンパイル時オプションLUA_COMPAT_VARARG
を参照。) - for文とrepeat文の暗黙の変数のスコープに微妙な変更がありました。
- 長い文字列/長いコメントの構文(
[[string]]
)では、ネストが許可されなくなりました。これらの場合には新しい構文([=[string]=]
)を使用できます。(luaconf.h
のコンパイル時オプションLUA_COMPAT_LSTR
を参照。)
7.2 – ライブラリの変更点
- 関数
string.gfind
はstring.gmatch
に名前が変更されました。(luaconf.hのコンパイル時オプションLUA_COMPAT_GFIND
を参照してください。) string.gsub
が第三引数に関数を持つ場合、この関数がnilまたはfalseを返すと、置換文字列は空の文字列ではなく、全体の一致部分になります。- 関数
table.setn
は非推奨となりました。関数table.getn
は新しい長さ演算子(#
)に対応しています。関数の代わりに演算子を使用してください。(luaconf.hのコンパイル時オプションLUA_COMPAT_GETN
を参照してください。) - 関数
loadlib
はpackage.loadlib
に名前が変更されました。(luaconf.hのコンパイル時オプションLUA_COMPAT_LOADLIB
を参照してください。) - 関数
math.mod
はmath.fmod
に名前が変更されました。(luaconf.hのコンパイル時オプションLUA_COMPAT_MOD
を参照してください。) - 関数
table.foreach
とtable.foreachi
は非推奨となりました。pairs
またはipairs
を使用したforループを代わりに使用できます。 - 新しいモジュールシステムにより、関数
require
に大きな変更がありました。ただし、新しい動作は古い動作とほとんど互換性がありますが、require
はLUA_PATH
ではなくpackage.path
からパスを取得します。 - 関数
collectgarbage
は異なる引数を持ちます。関数gcinfo
は非推奨となり、代わりにcollectgarbage("count")
を使用してください。
7.3 – APIの変更点
- ライブラリを開くための
luaopen_*
関数は、通常のC関数のように直接呼び出すことができません。Lua関数のようにLuaを通じて呼び出す必要があります。 - 関数
lua_open
は、ユーザーがメモリ割り当て関数を設定できるようにlua_newstate
に置き換えられました。標準ライブラリのluaL_newstate
を使用して、reallocに基づく標準割り当て関数を持つ状態を作成できます。 - 補助ライブラリからの関数
luaL_getn
とluaL_setn
は非推奨です。luaL_getn
の代わりにlua_objlen
を使用し、luaL_setn
の代わりに何も使用しないでください。 - 関数
luaL_openlib
はluaL_register
に置き換えられました。 - 関数
luaL_checkudata
は、与えられた値が期待されるタイプのユーザーデータでない場合にエラーを投げるようになりました。(Lua 5.0ではNULLを返しました。)
8 – Luaの完全な構文
以下は拡張BNFで表されたLuaの完全な構文です。(演算子の優先順位については記述されていません。)
chunk ::= {stat [`;´]} [laststat [`;´]]
block ::= chunk
stat ::= varlist `=´ explist |
functioncall |
do block end |
while exp do block end |
repeat block until exp |
if exp then block {elseif exp then block} [else block] end |
for Name `=´ exp `,´ exp [`,´ exp] do block end |
for namelist in explist do block end |
function funcname funcbody |
local function Name funcbody |
local namelist [`=´ explist]
laststat ::= return [explist] | break
funcname ::= Name {`.´ Name} [`:´ Name]
varlist ::= var {`,´ var}
var ::= Name | prefixexp `[´ exp `]´ | prefixexp `.´ Name
namelist ::= Name {`,´ Name}
explist ::= {exp `,´} exp
exp ::= nil | false | true | Number | String | `...´ | function |
prefixexp | tableconstructor | exp binop exp | unop exp
prefixexp ::= var | functioncall | `(´ exp `)´
functioncall ::= prefixexp args | prefixexp `:´ Name args
args ::= `(´ [explist] `)´ | tableconstructor | String
function ::= function funcbody
funcbody ::= `(´ [parlist] `)´ block end
parlist ::= namelist [`,´ `...´] | `...´
tableconstructor ::= `{´ [fieldlist] `}´
fieldlist ::= field {fieldsep field} [fieldsep]
field ::= `[´ exp `]´ `=´ exp | Name `=´ exp | exp
fieldsep ::= `,´ | `;´
binop ::= `+´ | `-´ | `*´ | `/´ | `^´ | `%´ | `..´ |
`<´ | `<=´ | `>´ | `>=´ | `==´ | `~=´ |
and | or
unop ::= `-´ | not | `#´