Skip to content

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での名前(識別子とも呼ばれる)は、文字、数字、アンダースコアの任意の文字列で、数字で始まらないものです。これはほとんどの言語での名前の定義と一致します。(文字の定義は現在のロケールに依存します:現在のロケールでアルファベットと見なされる任意の文字が識別子に使用できます。)識別子は、変数やテーブルフィールドを命名するために使用されます。

次のキーワードは予約されており、名前として使用することはできません:

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

Luaは大文字と小文字を区別する言語です:andは予約語ですが、AndANDは異なる有効な名前です。慣例として、アンダースコアに続く大文字(例えば_VERSION)で始まる名前は、Luaによって使用される内部のグローバル変数に予約されています。

次の文字列は他のトークンを示します:

txt
+     -     *     /     %     ^     #
==    ~=    <=    >=    <     >     =
(     )     {     }     [     ]
;     :     ,     .     ..    ...

リテラル文字列は、一致する単一または二重引用符で区切ることができ、次の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としてコード化されます)、以下の五つのリテラル文字列は同じ文字列を示します:

lua
a = 'alo\n123"'
a = "alo\n123\""
a = '\97lo\10\04923"'
a = [[alo
123"]]
a = [==[
alo
123"]==]

数値定数は、オプションで小数部と小数指数を付けて書くことができます。Luaは整数の16進定数も受け入れ、これには0xを前置します。有効な数値定数の例は以下の通りです。

txt
3   3.0   3.1416   314.16e-2   0.31416E1   0xff   0x56

コメントは、文字列の外部のどこでも二つのハイフン(--)で始まります。--の直後のテキストが開始長い括弧でない場合、そのコメントは短いコメントであり、行の終わりまで続きます。そうでなければ、それは長いコメントであり、対応する閉じ長い括弧まで続きます。長いコメントは、コードを一時的に無効にするために頻繁に使用されます。

2.2 – 値と型

Luaは動的型付け言語です。これは、変数に型がなく、値にのみ型があることを意味します。言語には型定義がありません。すべての値は自身の型を持ちます。

Luaのすべての値はファーストクラスの値です。これは、すべての値を変数に格納したり、他の関数への引数として渡したり、結果として返すことができることを意味します。

Luaには8つの基本型があります:nilbooleannumberstringfunctionuserdatathread、そしてtableです。nilは値nilの型であり、他のいかなる値とも異なることが主な特徴で、通常は有用な値の欠如を表します。booleanは値falsetrueの型です。nilfalseの両方が条件を偽にします。それ以外の値は条件を真にします。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には三種類の変数があります:グローバル変数、ローカル変数、およびテーブルフィールド。

単一の名前は、グローバル変数、ローカル変数(または関数の形式的なパラメータである、特定の種類のローカル変数)を示すことができます:

txt
var ::= Name

Nameは、§2.1で定義されているように、識別子を示します。

変数は明示的にローカルと宣言されない限り、グローバルと見なされます(§2.4.7を参照)。ローカル変数はレキシカルスコープです:ローカル変数は、そのスコープ内で定義された関数によって自由にアクセスできます(§2.6を参照)。

変数への最初の代入の前に、その値はnilです。

テーブルのインデックスには角括弧が使用されます:

txt
var ::= prefixexp `[´ exp `]´

グローバル変数とテーブルフィールドへのアクセスの意味は、メタテーブルを介して変更することができます。インデックス付き変数t[i]へのアクセスは、gettable_event(t,i)の呼び出しに相当します。(gettable_event関数の完全な説明については§2.8を参照してください。この関数はLuaでは定義されておらず、呼び出すこともできません。ここでは説明目的でのみ使用しています。)

構文var.Nameは、var["Name"]のための単なるシンタックスシュガーです:

txt
var ::= prefixexp `.´ Name

すべてのグローバル変数は、環境テーブルまたは単に環境と呼ばれる通常のLuaテーブルのフィールドとして存在します(§2.9を参照)。各関数は自身の環境への参照を持っているので、この関数内のすべてのグローバル変数はこの環境テーブルを参照します。関数が作成されると、それは作成した関数の環境を継承します。Lua関数の環境テーブルを取得するにはgetfenvを呼び出します。それを置き換えるにはsetfenvを呼び出します。(C関数の環境はデバッグライブラリを通じてのみ操作できます;(§5.9を参照)。)

グローバル変数xへのアクセスは、_env.xに相当し、これはさらに

lua
gettable_event(_env, "x")

に相当します。ここで_envは実行中の関数の環境です。(gettable_event関数の完全な説明については§2.8を参照してください。この関数はLuaでは定義されておらず、呼び出すこともできません。同様に、_env変数もLuaで定義されていません。ここでは説明目的でのみ使用しています。)

2.4 – ステートメント

Luaは、PascalやCに似たほぼ従来のステートメントセットをサポートしています。このセットには、代入、制御構造、関数呼び出し、変数宣言が含まれます。

2.4.1 – チャンク

Luaの実行単位はチャンクと呼ばれます。チャンクは単に一連のステートメントであり、順番に実行されます。各ステートメントはオプションでセミコロンに続くことができます:

txt
chunk ::= {stat [`;´]}

空のステートメントは存在しないため、';;'は不正です。

Luaはチャンクを引数の数が可変である匿名関数の本体として扱います(§2.5.9を参照)。そのため、チャンクはローカル変数を定義し、引数を受け取り、値を返すことができます。

チャンクは、ホストプログラム内のファイルまたは文字列に格納することができます。チャンクを実行するには、Luaはまずチャンクを仮想マシンの命令にプリコンパイルし、次に仮想マシン用のインタプリタでコンパイルされたコードを実行します。

チャンクはバイナリ形式にプリコンパイルすることもできます。詳細はプログラムluacを参照してください。ソースとコンパイルされた形式のプログラムは互換性があり、Luaはファイルタイプを自動的に検出し、それに応じて動作します。

2.4.2 – ブロック

ブロックは、ステートメントのリストです。構文的には、ブロックはチャンクと同じです:

txt
block ::= chunk

ブロックは明示的に区切ることで単一のステートメントを生成することができます:

txt
stat ::= do block end

明示的なブロックは、変数宣言のスコープを制御するために役立ちます。明示的なブロックは、別のブロックの途中にreturnやbreakステートメントを追加するためにも時々使用されます(§2.4.4を参照)。

2.4.3 – 代入

Luaは複数の代入を許可します。したがって、代入の構文では、左側に変数のリスト、右側に式のリストが定義されます。両リストの要素はコンマで区切られます:

txt
stat ::= varlist `=´ explist
varlist ::= var {`,´ var}
explist ::= exp {`,´ exp}

式については§2.5で議論されます。

代入の前に、値のリストは変数のリストの長さに調整されます。必要以上の値がある場合、余分な値は捨てられます。必要な値が足りない場合、リストは必要な数のnilで拡張されます。式のリストが関数呼び出しで終わる場合、その呼び出しによって返されるすべての値が調整の前に値のリストに入ります(呼び出しが括弧で囲まれている場合を除く;§2.5を参照)。

代入文は、最初にすべての式を評価し、その後に代入が行われます。したがって、コード

lua
i = 3
i, a[i] = i+1, 20

a[3]を20に設定し、a[i]のiが4に割り当てられる前に(3として)評価されるため、a[4]には影響を与えません。同様に、行

lua
x, y = y, x

はxとyの値を交換し、

lua
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という代入に等しく、これはさらに

lua
settable_event(_env, "x", val)

と等価です。ここで_envは実行中の関数の環境です。(_env変数はLuaで定義されていません。ここでは説明の目的でのみ使用します。)

2.4.4 – 制御構造

制御構造ifwhilerepeatは、通常の意味と馴染みのある構文を持っています:

txt
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を参照)。

制御構造の条件式は任意の値を返すことができます。falsenilは偽と見なされます。nilfalse以外のすべての値は真と見なされます(特に、数字の0と空の文字列も真です)。

repeat–untilループでは、内部ブロックはuntilキーワードで終了するのではなく、条件の後でのみ終了します。したがって、条件はループブロック内で宣言されたローカル変数を参照することができます。

return文は、関数またはチャンク(実質的には関数です)から値を返すために使用されます。関数とチャンクは複数の値を返すことができるため、return文の構文は次のようになります:

txt
stat ::= return [explist]

break文は、whilerepeat、またはforループの実行を終了し、ループの次の文へスキップするために使用されます:

txt
stat ::= break

breakは最も内側のループを終了させます。

return文とbreak文は、ブロックの最後の文としてのみ書くことができます。ブロックの途中でreturnまたはbreakを実行する必要がある場合は、do return enddo break endの慣用句にあるように、明示的な内部ブロックを使用できます。なぜなら、returnbreakはそれぞれの(内部)ブロックで最後の文になるからです。

2.4.5 – For文

for文には数値形式と汎用形式の2つの形式があります。

数値forループは、制御変数が算術進行を通過する間、コードブロックを繰り返します。次の構文を持っています:

txt
stat ::= for Name `=´ exp `,´ exp [`,´ exp] do block end

このブロックは、最初のexpの値から始まり、第二のexpを第三のexpのステップで超えるまで繰り返されます。より正確には、以下のようなfor

lua
for v = e1, e2, e3 do block end

は次のコードと等価です:

lua
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つの制御式はループ開始前に一度だけ評価されます。すべて数値として評価されなければなりません。
  • varlimitstepは見えない変数です。ここで示されている名前は説明の目的のみのものです。
  • 第三の式(ステップ)がない場合は、ステップ1が使用されます。
  • forループを抜けるにはbreakを使用できます。
  • ループ変数vはループにローカルです。forが終了するか中断された後、その値を使用することはできません。この値が必要な場合は、ループを抜ける前に別の変数に割り当ててください。

汎用for文は関数、つまりイテレータ上で動作します。各繰り返しで、イテレータ関数が呼び出されて新しい値を生成し、この新しい値がnilになったときに停止します。汎用forループの構文は次のとおりです:

txt
stat ::= for namelist in explist do block end
namelist ::= Name {`,´ Name}

次のようなfor

lua
for var_1, ···, var_n in explist do block end

は次のコードと等価です:

lua
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は一度だけ評価されます。その結果はイテレータ関数、状態、および最初のイテレータ変数の初期値です。
  • fs、およびvarは見えない変数です。名前はここで説明目的のみです。
  • forループを抜けるにはbreakを使用できます。
  • ループ変数var_iはループにローカルです。forが終了した後、これらの値を使用することはできません。これらの値が必要な場合は、ループを抜ける前に他の変数に割り当ててください。

2.4.6 – 文としての関数呼び出し

副作用があるかもしれないため、関数呼び出しは文として実行できます:

txt
stat ::= functioncall

この場合、すべての返された値は破棄されます。関数呼び出しについては§2.5.8で説明されています。

2.4.7 – ローカル宣言

ローカル変数はブロック内のどこでも宣言できます。宣言には初期代入を含めることができます:

txt
stat ::= local namelist [`=´ explist]

初期代入がある場合、そのセマンティクスは複数代入と同じです(§2.4.3を参照)。そうでない場合、すべての変数はnilで初期化されます。

チャンクもブロックです(§2.4.1を参照)、したがってローカル変数は明示的なブロックの外のチャンクで宣言できます。そのようなローカル変数のスコープはチャンクの終わりまで広がります。

ローカル変数の可視性ルールについては§2.6で説明されています。

2.5 – 式

Luaの基本的な式は以下の通りです:

txt
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つを除いてすべての値を破棄します。

以下に例を示します:

lua
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の平方根の逆数を計算します。剰余は以下のように定義されます:

lua
a % b == a - math.floor(a/b) * b

つまり、商をマイナス無限大に丸めた除算の剰余です。

2.5.2 – 関係演算子

Luaの関係演算子は以下の通りです:

  • ==
  • ~=
  • <
  • >
  • <=
  • >=

これらの演算子の結果は常にfalseまたはtrueです。

等価演算子(==)はまずオペランドの型を比較します。型が異なる場合、結果はfalseになります。そうでなければ、オペランドの値が比較されます。数値と文字列は通常の方法で比較されます。オブジェクト(テーブル、ユーザデータ、スレッド、関数)は参照によって比較されます:2つのオブジェクトが同じオブジェクトである場合にのみ等しいと見なされます。新しいオブジェクト(テーブル、ユーザデータ、スレッド、または関数)を作成するたびに、この新しいオブジェクトは以前に存在した任意のオブジェクトと異なります。

Luaでテーブルやユーザデータの比較方法を変更するには、"eq"メタメソッドを使用できます(§2.8を参照)。

等価性比較には§2.2.1の変換規則は適用されません。したがって、"0"==0falseと評価され、t[0]t["0"]はテーブル内の異なるエントリを示します。

~=演算子は等価(==)の正確な否定です。

順序演算子は次のように機能します。両方の引数が数値の場合、そのように比較されます。さもなければ、両方の引数が文字列の場合、現在のロケールに従って値が比較されます。さもなければ、Luaは"lt"または"le"メタメソッドを呼び出そうとします(§2.8を参照)。比較a > bb < aに、a >= bb <= aに変換されます。

2.5.3 – 論理演算子

Luaの論理演算子はandornotです。制御構造(§2.4.4を参照)と同様に、すべての論理演算子はfalsenilfalseとみなし、それ以外のものをtrueとみなします。

否定演算子notは常にfalseまたはtrueを返します。論理積演算子andは、その第一引数がfalseまたはnilの場合にその値を返し、それ以外の場合は第二引数を返します。論理和演算子orは、その第一引数がnilfalse以外の場合にその値を返し、それ以外の場合は第二引数を返します。andorはどちらもショートカット評価を使用します。つまり、第二オペランドは必要に応じてのみ評価されます。ここにいくつかの例を示します:

lua
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値がある場合)がある場合、#tnil値の直前の任意のインデックスになる可能性があります(つまり、配列の終わりとしてそのようなnil値を考慮することがあります)。

2.5.6 – 優先順位

Luaにおける演算子の優先順位は、以下の表に従い、低いものから高いものへとなります:

  • or
  • and
  • < > <= >= ~= ==
  • ..
  • + -
  • * / %
  • not # - (単項)
  • ^

通常、括弧を使用して式の優先順位を変更できます。連結(..)と累乗(^)演算子は右結合です。他のすべての二項演算子は左結合です。

2.5.7 – テーブルコンストラクタ

テーブルコンストラクタは、テーブルを生成する式です。コンストラクタが評価されるたびに新しいテーブルが作成されます。コンストラクタは、空のテーブルを作成するか、またはテーブルを作成してそのいくつかのフィールドを初期化するために使用できます。コンストラクタの一般的な構文は以下の通りです:

txt
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から始まる連続した数値整数です。他の形式のフィールドはこのカウントに影響を与えません。例えば、

lua
a = { [f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45 }

は以下と等価です:

lua
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での関数呼び出しは次の構文を持ちます:

txt
functioncall ::= prefixexp args

関数呼び出しでは、最初にprefixexpargsが評価されます。prefixexpの値の型が関数であれば、指定された引数でこの関数が呼び出されます。そうでなければ、prefixexpの"call"メタメソッドが呼び出され、最初のパラメーターとしてprefixexpの値が渡され、その後に元の呼び出し引数が続きます(§2.8を参照)。

以下の形式

txt
functioncall ::= prefixexp ':' Name args

は"メソッド"の呼び出しに使用できます。呼び出しv:name(args)v.name(v,args)の糖衣構文ですが、vは一度だけ評価されます。

引数は次の構文を持ちます:

txt
args ::= '(' [explist] ')'
args ::= tableconstructor
args ::= String

すべての引数表現は呼び出し前に評価されます。形式f{fields}の呼び出しはf({fields})の糖衣構文です。つまり、引数リストは単一の新しいテーブルです。形式f'string'(またはf"string"f[[string]])の呼び出しはf('string')の糖衣構文です。つまり、引数リストは単一のリテラル文字列です。

Luaの自由形式構文の例外として、関数呼び出しでは'('の前に改行を入れることはできません。この制約は言語内のある種の曖昧さを避けるためのものです。もし

lua
a = f
(g).x(a)

と書いた場合、Luaはこれを単一の文a = f(g).x(a)と見なします。従って、2つの文が欲しい場合は、それらの間にセミコロンを加える必要があります。実際にfを呼び出したい場合は、(g)の前の改行を削除する必要があります。

形式return functioncallの呼び出しは末尾呼び出しと呼ばれます。Luaは適切な末尾呼び出し(または適切な末尾再帰)を実装しています:末尾呼び出しでは、呼ばれた関数が呼び出し関数のスタックエントリを再利用します。したがって、プログラムが実行できるネストされた末尾呼び出しの数には制限がありません。ただし、末尾呼び出しは呼び出し関数に関するデバッグ情報を消去します。末尾呼び出しは特定の構文でのみ発生することに注意してください。この構文では、returnは単一の関数呼び出しを引数とし、呼び出し関数は呼び出された関数の返り値を正確に返します。したがって、以下の例は末尾呼び出しではありません:

lua
return (f(x))        -- 1つの結果に調整されます
return 2 * f(x)
return x, f(x)       -- 追加の結果
f(x); return         -- 結果が破棄されます
return x or f(x)     -- 1つの結果に調整されます

2.5.9 – 関数定義

関数定義の構文は以下の通りです:

txt
function ::= function funcbody
funcbody ::= '(' [parlist] ')' block end

関数定義を簡略化するための糖衣構文は次のとおりです:

txt
stat ::= function funcname funcbody
stat ::= local function Name funcbody
funcname ::= Name {'.' Name} [':' Name]

次のステートメント

lua
function f () body end

は以下に変換されます:

lua
f = function () body end

次のステートメント

lua
function t.a.b.c.f () body end

は以下に変換されます:

lua
t.a.b.c.f = function () body end

次のステートメント

lua
local function f () body end

は以下に変換されます:

lua
local f; f = function () body end

以下のようには変換されません:

lua
local f = function () body end

(これは関数の本体がfを参照している場合にのみ差が出ます。)

関数定義は実行可能な式であり、その値の型はfunctionです。Luaがチャンクをプリコンパイルすると、そのすべての関数本体もプリコンパイルされます。そして、Luaが関数定義を実行するたびに、関数はインスタンス化(またはクローズ)されます。この関数インスタンス(またはクロージャ)は式の最終値です。同じ関数の異なるインスタンスは、異なる外部ローカル変数を参照したり、異なる環境テーブルを持つことができます。

パラメータは引数の値で初期化されるローカル変数として機能します:

txt
parlist ::= namelist [',' '...'] | '...'

関数が呼び出されると、引数のリストはパラメータリストの長さに調整されます。ただし、関数が可変長またはvararg関数の場合はこの限りではありません。これは、パラメータリストの末尾に3つのドット(...)によって示されます。vararg関数は引数リストを調整しません。代わりに、すべての追加引数を収集し、これらを関数にvararg式を通じて提供します。この式も3つのドットで書かれます。この式の値は、複数の結果を持つ関数のように、すべての実際の追加引数のリストです。vararg式が別の式内や式のリストの途中で使用される場合、その戻りリストは1つの要素に調整されます。式が式のリストの最後の要素として使用される場合、調整は行われません(最後の式が括弧で囲まれている場合を除く)。

例として、次の定義を考えてみましょう:

lua
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を持つ関数、つまりメソッドを定義するために使用されます。したがって、文

lua
function t.a.b.c:f (params) body end

は、以下のためのシンタックスシュガーです:

lua
t.a.b.c.f = function (self, params) body end

2.6 – 可視性ルール

Luaはレキシカルスコープ言語です。変数のスコープは宣言後の最初の文から始まり、宣言を含む最も内側のブロックの終わりまで続きます。以下の例を考えてみましょう:

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は外側の変数を指します。

レキシカルスコープのルールのため、ローカル変数はそのスコープ内で定義された関数によって自由にアクセスできます。内部関数によって使用されるローカル変数は、内部関数内でアップバリューまたは外部ローカル変数と呼ばれます。

ローカル文の各実行が新しいローカル変数を定義することに注意してください。次の例を考えてみましょう:

lua
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のコードは説明用です。実際の振る舞いはインタプリタにハードコードされており、このシミュレーションよりもはるかに効率的です。これらの説明で使用されるすべての関数(rawgettonumberなど)は§5.1で説明されています。特に、与えられたオブジェクトのメタメソッドを取得するには、次の式を使用します

lua
metatable(obj)[event]

これは以下のように読むべきです

lua
rawget(getmetatable(obj) or {}, event)

つまり、メタメソッドへのアクセスは他のメタメソッドを呼び出さず、メタテーブルを持たないオブジェクトへのアクセスが失敗することはありません(単にnilを返します)。

  • "add":+ 操作です。

以下のgetbinhandler関数は、Luaが二項演算のハンドラーをどのように選択するかを定義しています。まず、Luaは最初のオペランドを試します。その型が操作のハンドラーを定義していない場合、Luaは2番目のオペランドを試します。

lua
function getbinhandler (op1, op2, event)
  return metatable(op1)[event] or metatable(op2)[event]
end

この関数を使用すると、op1 + op2の振る舞いは次のようになります:

lua
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":単項- 演算。
lua
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": ..(連結)操作です。
lua
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": #操作です。
lua
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が比較演算子のメタメソッドを選択する方法を定義します。メタメソッドは、比較される両方のオブジェクトが同じ型であり、選択された操作のための同じメタメソッドを持っている場合にのみ選択されます。
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"イベントは次のように定義されます:

lua
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 ~= bnot (a == b)と等価です。

  • "lt": < 操作。
lua
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 > bb < aと等価です。

  • "le": <= 操作。
lua
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 >= bb <= aと等価です。"le"メタメソッドがない場合、Luaは"lt"を試み、a <= bnot (b < a)と等価であると仮定します。

  • "index": インデクシングアクセスtable[key]
lua
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
lua
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が値を呼び出すときに呼び出される。
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関数(loadfileloadstring、または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に対して行います:

lua
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はエラーをキャッチしません。任意のエラーは呼び出し元に伝播されます。

例として、以下のコードを考えてください:

lua
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"))

実行すると、次の出力が得られます:

txt
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を通じて設定した最大スタックサイズまでのインデックスです。このようなインデックスは許容インデックスと呼ばれます。より形式的に、許容インデックスを次のように定義します:

lua
(index < 0 && abs(index) <= top) ||
(index > 0 && index <= stackspace)

0が許容インデックスであることは決してありません。

3.3 – 擬似インデックス

特に断りがない限り、有効なインデックスを受け入れる任意の関数は、スタック内にはないがCコードからアクセス可能なLuaの値を表す擬似インデックスで呼び出すこともできます。擬似インデックスは、スレッド環境、関数環境、レジストリ、およびC関数のアップバリューにアクセスするために使用されます(§3.4を参照)。

スレッド環境(グローバル変数が存在する場所)は常に擬似インデックスLUA_GLOBALSINDEXにあります。実行中のC関数の環境は常に擬似インデックスLUA_ENVIRONINDEXにあります。

グローバル変数の値にアクセスして変更するには、環境テーブルに対する通常のテーブル操作を使用できます。例えば、グローバル変数の値にアクセスするには、次の操作を行います:

c
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

c
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);

Luaステートによって使用されるメモリ割り当て関数の型です。割り当て関数はreallocに似た機能を提供する必要がありますが、全く同じではありません。その引数はudで、lua_newstateに渡される不透明なポインタです。ptrは、割り当て/再割り当て/解放されるブロックへのポインタです。osizeはブロックの元のサイズ、nsizeはブロックの新しいサイズです。ptrosizeがゼロの場合、かつその場合に限りNULLです。nsizeがゼロのとき、割り当て関数はNULLを返す必要があります。osizeがゼロでない場合、ptrを指すブロックを解放する必要があります。nsizeがゼロでないとき、割り当て関数は要求を満たせない場合にのみNULLを返します。nsizeがゼロでなく、osizeがゼロのとき、割り当て関数はmallocのように振る舞うべきです。nsizeosizeがゼロでない場合、割り当て関数はreallocのように振る舞います。Luaは、osize >= nsizeのとき割り当て関数が決して失敗しないと仮定しています。

こちらは割り当て関数のシンプルな実装です。これは補助ライブラリによってluaL_newstateで使用されます。

c
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

c
// [-0, +0, -]
lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf);

新しいパニック関数を設定し、古いものを返します。

保護された環境の外でエラーが発生した場合、Luaはパニック関数を呼び出し、その後exit(EXIT_FAILURE)を呼び出してホストアプリケーションを終了します。パニック関数は(例えば長いジャンプを行うことで)この終了を回避できます。

パニック関数はスタックの先頭にあるエラーメッセージにアクセスできます。

lua_call

c
// [-(nargs + 1), +nresults, e]
void lua_call (lua_State *L, int nargs, int nresults);

関数を呼び出します。

関数を呼び出すには、次のプロトコルを使用する必要があります:まず、呼び出される関数がスタックにプッシュされます。次に、関数への引数が直接の順番でプッシュされます。つまり、最初の引数が最初にプッシュされます。最後にlua_callを呼び出します。nargsはスタックにプッシュした引数の数です。すべての引数と関数の値は、関数が呼び出されるときにスタックからポップされます。関数の結果は、関数が戻るとスタックにプッシュされます。結果の数はnresultsに調整されます。ただし、nresultsLUA_MULTRETの場合は、関数からのすべての結果がプッシュされます。Luaは、返された値がスタックスペースに収まるようにします。関数の結果は直接の順序でスタックにプッシュされます(最初の結果が最初にプッシュされる)ので、呼び出しの後に最後の結果がスタックの上にあります。

呼び出された関数内の任意のエラーは上方に伝播されます(longjmpを使用)。

以下の例は、ホストプログラムがこのLuaコードに相当することをどのように行うかを示しています:

lua
a = f("how", t.x, 14)

C言語での実装は次のとおりです:

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

c
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関数も多くの結果を返すことができます。

例として、次の関数は可変数の数値引数を受け取り、その平均値と合計値を返します:

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

c
// [-0, +0, m]
int lua_checkstack (lua_State *L, int extra);

スタックに少なくともextraの空きスロットがあることを保証します。スタックをそのサイズまで増やすことができない場合はfalseを返します。この関数はスタックを縮小することはありません。スタックが新しいサイズよりも既に大きい場合、それは変更されません。

lua_close

c
// [-0, +0, -]
void lua_close (lua_State *L);

指定されたLuaステート内のすべてのオブジェクトを破壊し(該当するガーベジコレクションメタメソッドがある場合は呼び出します)、このステートによって使用されるすべての動的メモリを解放します。いくつかのプラットフォームでは、ホストプログラムが終了するとすべてのリソースが自然に解放されるため、この関数を呼び出す必要はないかもしれません。一方で、デーモンやWebサーバーなどの長時間実行されるプログラムは、不要になったらすぐにステートを解放する必要があるかもしれません。これは、サイズが大きくなりすぎるのを避けるためです。

lua_concat

c
// [-n, +1, e]
void lua_concat (lua_State *L, int n);

スタックの上部にあるn個の値を連結し、それらをポップして、結果をスタックの上部に残します。nが1の場合、結果はスタック上の単一の値です(つまり、関数は何もしません)。nが0の場合、結果は空の文字列です。連結はLuaの通常のセマンティクスに従って行われます(§2.5.4を参照)。

lua_cpcall

c
// [-0, +(0|1), -]
int lua_cpcall (lua_State *L, lua_CFunction func, void *ud);

保護モードでC関数funcを呼び出します。funcはスタックにudを含むライトユーザーデータのみで開始します。エラーが発生した場合、lua_cpcalllua_pcallと同じエラーコードを返し、スタックの上部にエラーオブジェクトを返します。そうでない場合はゼロを返し、スタックを変更しません。funcによって返されたすべての値は破棄されます。

lua_createtable

c
// [-0, +1, m]
void lua_createtable (lua_State *L, int narr, int nrec);

新しい空のテーブルを作成し、それをスタックにプッシュします。新しいテーブルは、narr配列要素とnrec非配列要素用に事前に割り当てられたスペースを持ちます。この事前割り当ては、テーブルが持つ要素の正確な数を知っている場合に便利です。それ以外の場合は、関数lua_newtableを使用できます。

lua_dump

c
// [-0, +0, m]
int lua_dump (lua_State *L, lua_Writer writer, void *data);

関数をバイナリチャンクとしてダンプします。スタックの先頭にあるLua関数を受け取り、再度ロードすると元の関数と同等の関数となるバイナリチャンクを生成します。チャンクの一部を生成すると、lua_dumpは与えられたデータでそれらを書き込むために関数ライター(lua_Writer参照)を呼び出します。

戻り値は、ライターへの最後の呼び出しによって返されたエラーコードです。0はエラーがないことを意味します。

この関数はスタックからLua関数をポップしません。

lua_equal

c
// [-0, +0, e]
int lua_equal (lua_State *L, int index1, int index2);

許容されるインデックスindex1index2にある2つの値が等しい場合に1を返し、Luaの==演算子のセマンティクスに従います(つまり、メタメソッドを呼び出す可能性があります)。それ以外の場合は0を返します。いずれかのインデックスが無効である場合も0を返します。

lua_error

c
// [-1, +0, v]
int lua_error (lua_State *L);

Luaエラーを生成します。エラーメッセージ(実際には任意の型のLua値になり得ます)はスタックの先頭になければなりません。この関数はロングジャンプを行うため、決して戻りません(luaL_errorを参照)。

lua_gc

c
// [-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

c
// [-0, +0, -]
lua_Alloc lua_getallocf (lua_State *L, void **ud);

特定のステートのメモリ割り当て関数を返します。udがNULLでない場合、Luaは*udlua_newstateに渡された不透明なポインタを格納します。

lua_getfenv

c
// [-0, +1, -]
void lua_getfenv (lua_State *L, int index);

指定されたインデックスにある値の環境テーブルをスタックにプッシュします。

lua_getfield

c
// [-0, +1, e]
void lua_getfield (lua_State *L, int index, const char *k);

スタックに値t[k]をプッシュします。ここでtは指定された有効なインデックスの値です。Luaと同様に、この関数は"index"イベントに対するメタメソッドをトリガーすることがあります(§2.8参照)。

lua_getglobal

c
// [-0, +1, e]
void lua_getglobal (lua_State *L, const char *name);

グローバル変数nameの値をスタックにプッシュします。マクロとして定義されています:

c
#define lua_getglobal(L,s)  lua_getfield(L, LUA_GLOBALSINDEX, s)

lua_getmetatable

c
// [-0, +(0|1), -]
int lua_getmetatable (lua_State *L, int index);

指定された許容インデックスにある値のメタテーブルをスタックにプッシュします。インデックスが無効である場合、または値にメタテーブルがない場合、関数は0を返し、スタックに何もプッシュしません。

lua_gettable

c
// [-1, +1, e]
void lua_gettable (lua_State *L, int index);

t[k]の値をスタックにプッシュします。ここでtは指定された有効なインデックスにおける値であり、kはスタックの上部にある値です。

この関数はスタックからキーをポップします(結果の値をその場所に置きます)。Luaと同様に、この関数は"index"イベントのメタメソッドをトリガーする可能性があります(§2.8参照)。

lua_gettop

c
// [-0, +0, -]
int lua_gettop (lua_State *L);

スタックの最上位要素のインデックスを返します。インデックスは1から始まるため、この結果はスタック内の要素の数と等しくなります(したがって0は空のスタックを意味します)。

lua_insert

c
// [-1, +1, -]
void lua_insert (lua_State *L, int index);

上部の要素を指定された有効なインデックスに移動し、このインデックスより上の要素をシフトアップしてスペースを開けます。擬似インデックスでは呼び出せません。なぜなら、擬似インデックスは実際のスタック位置ではないからです。

lua_Integer

c
typedef ptrdiff_t lua_Integer;

Lua APIが整数値を表すために使用する型です。

デフォルトではptrdiff_tであり、これは通常、マシンが「快適に」扱うことができる最大の符号付き整数型です。

lua_isboolean

c
// [-0, +0, -]
int lua_isboolean (lua_State *L, int index);

指定された許容インデックスにある値がブール型である場合は1を返し、そうでない場合は0を返します。

lua_iscfunction

c
// [-0, +0, -]
int lua_iscfunction (lua_State *L, int index);

指定された許容インデックスにある値がC関数であれば1を返し、そうでなければ0を返します。

lua_isfunction

c
// [-0, +0, -]
int lua_isfunction (lua_State *L, int index);

指定された許容インデックスにある値が関数(CまたはLuaのいずれか)であれば1を返し、そうでなければ0を返します。

lua_islightuserdata

c
// [-0, +0, -]
int lua_islightuserdata (lua_State *L, int index);

指定された許容インデックスにある値がライトユーザーデータであれば1を返し、そうでなければ0を返します。

lua_isnil

c
// [-0, +0, -]
int lua_isnil (lua_State *L, int index);

指定された許容インデックスにある値がnilであれば1を返し、そうでなければ0を返します。

lua_isnone

c
// [-0, +0, -]
int lua_isnone (lua_State *L, int index);

指定された許容インデックスが無効である(つまり、現在のスタックの外部の要素を指している)場合は1を返し、そうでなければ0を返します。

lua_isnoneornil

c
// [-0, +0, -]
int lua_isnoneornil (lua_State *L, int index);

指定された許容インデックスが無効(つまり、現在のスタックの外部の要素を指している)であるか、このインデックスの値がnilであれば1を返し、そうでなければ0を返します。

lua_isnumber

c
// [-0, +0, -]
int lua_isnumber (lua_State *L, int index);

指定された許容インデックスにある値が数値または数値に変換可能な文字列であれば1を返し、そうでなければ0を返します。

lua_isstring

c
// [-0, +0, -]
int lua_isstring (lua_State *L, int index);

指定された許容インデックスにある値が文字列または数値(数値は常に文字列に変換可能)であれば1を返し、そうでなければ0を返します。

lua_istable

c
// [-0, +0, -]
int lua_istable (lua_State *L, int index);

指定された許容インデックスにある値がテーブルであれば1を返し、そうでなければ0を返します。

lua_isthread

c
// [-0, +0, -]
int lua_isthread (lua_State *L, int index);

指定された許容インデックスにある値がスレッドであれば1を返し、そうでなければ0を返します。

lua_isuserdata

c
// [-0, +0, -]
int lua_isuserdata (lua_State *L, int index);

指定された許容インデックスにある値がユーザーデータ(フルまたはライト)であれば1を返し、そうでなければ0を返します。

lua_lessthan

c
// [-0, +0, e]
int lua_lessthan (lua_State *L, int index1, int index2);

Luaの<演算子のセマンティクスに従い(つまり、メタメソッドを呼び出す可能性があります)、許容されるインデックスindex1にある値がindex2にある値より小さい場合は1を返し、そうでなければ0を返します。いずれかのインデックスが無効である場合も0を返します。

lua_load

c
// [-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

c
// [-0, +0, -]
lua_State *lua_newstate (lua_Alloc f, void *ud);

新しい、独立したステートを作成します。ステートを作成できない(メモリ不足のため)場合はNULLを返します。f引数はアロケータ関数で、このステートのためのすべてのメモリ割り当てはこの関数を通じて行われます。2番目の引数udは、Luaがすべての呼び出しでアロケータに単純に渡す不透明なポインタです。

lua_newtable

c
// [-0, +1, m]
void lua_newtable (lua_State *L);

新しい空のテーブルを作成し、スタックにプッシュします。これはlua_createtable(L, 0, 0)と等価です。

lua_newthread

c
// [-0, +1, m]
lua_State *lua_newthread (lua_State *L);

新しいスレッドを作成し、スタックにプッシュし、この新しいスレッドを表すlua_Stateへのポインタを返します。この関数によって返される新しいステートは、元のステートとすべてのグローバルオブジェクト(テーブルなど)を共有しますが、独立した実行スタックを持ちます。

スレッドを閉じるまたは破壊するための明示的な関数はありません。スレッドは、任意のLuaオブジェクトと同様に、ガーベジコレクションの対象です。

lua_newuserdata

c
// [-0, +1, m]
void *lua_newuserdata (lua_State *L, size_t size);

この関数は指定されたサイズの新しいメモリブロックを割り当て、そのブロックのアドレスを持つ新しいフルユーザーデータをスタックにプッシュし、このアドレスを返します。

ユーザーデータはLua内のCの値を表します。フルユーザーデータはメモリブロックを表します。それはオブジェクト(テーブルのような)です:作成する必要があり、自身のメタテーブルを持つことができ、収集されているときに検出することができます。フルユーザーデータはそれ自体(生の等価性の下で)にのみ等しいです。

Luaがgcメタメソッドを持つフルユーザーデータを収集するとき、Luaはメタメソッドを呼び出し、ユーザーデータを最終化されたとマークします。このユーザーデータが再び収集されると、Luaは対応するメモリを解放します。

lua_next

c
// [-1, +(2|0), e]
int lua_next (lua_State *L, int index);

スタックからキーをポップし、指定されたインデックスのテーブルからキーと値のペア(与えられたキーの「次」のペア)をプッシュします。テーブル内に他の要素がない場合、lua_nextは0を返します(何もプッシュしません)。

典型的な走査は次のようになります:

c
/* 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

c
typedef double lua_Number;

Luaの数値の型です。デフォルトではdoubleですが、luaconf.hで変更することができます。

設定ファイルを通じて、数値のための別の型(例えば、floatやlong)でLuaを動作させるように変更できます。

lua_objlen

c
// [-0, +0, -]
size_t lua_objlen (lua_State *L, int index);

指定された許容インデックスにある値の「長さ」を返します:文字列の場合は文字列の長さ、テーブルの場合は長さ演算子('#')の結果、ユーザーデータの場合はユーザーデータに割り当てられたメモリブロックのサイズ、他の値の場合は0です。

lua_pcall

c
// [-(nargs + 1), +(nresults|1), -]
int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc);

保護モードで関数を呼び出します。

nargsnresultslua_callと同じ意味を持ちます。呼び出し中にエラーがなければ、lua_pcalllua_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

c
// [-n, +0, -]
void lua_pop (lua_State *L, int n);

スタックからn個の要素をポップします。

lua_pushboolean

c
// [-0, +1, -]
void lua_pushboolean (lua_State *L, int b);

真偽値bをスタックにプッシュします。

lua_pushcclosure

c
// [-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

c
// [-0, +1, m]
void lua_pushcfunction (lua_State *L, lua_CFunction f);

C関数をスタックにプッシュします。この関数はC関数へのポインタを受け取り、呼び出されると対応するC関数を起動する型functionのLua値をスタックにプッシュします。

Luaに登録される任意の関数は、そのパラメータを受け取り結果を返すための正しいプロトコルに従う必要があります(lua_CFunctionを参照)。

lua_pushcfunctionはマクロとして定義されています:

c
#define lua_pushcfunction(L,f)  lua_pushcclosure(L,f,0)

lua_pushfstring

c
// [-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

c
// [-0, +1, -]
void lua_pushinteger (lua_State *L, lua_Integer n);

nの数値をスタックにプッシュします。

lua_pushlightuserdata

c
// [-0, +1, -]
void lua_pushlightuserdata (lua_State *L, void *p);

ライトユーザーデータをスタックにプッシュします。

ユーザーデータはLua内のC値を表します。ライトユーザーデータはポインタを表します。それは値(数値のような)です:作成することはありません、個別のメタテーブルを持たない、そして集められることはありません(それは決して作成されなかったので)。ライトユーザーデータは、同じCアドレスを持つ任意のライトユーザーデータと等しいです。

lua_pushliteral

c
// [-0, +1, m]
void lua_pushliteral (lua_State *L, const char *s);

このマクロはlua_pushlstringと等価ですが、sがリテラル文字列である場合のみ使用できます。これらの場合、自動的に文字列の長さを提供します。

lua_pushlstring

c
// [-0, +1, m]
void lua_pushlstring (lua_State *L, const char *s, size_t len);

sが指す長さlenの文字列をスタックにプッシュします。Luaは与えられた文字列の内部コピーを作成(または再利用)しますので、関数が戻った直後にsのメモリを解放または再利用できます。文字列には組み込みのゼロを含めることができます。

lua_pushnil

c
// [-0, +1, -]
void lua_pushnil (lua_State *L);

nil値をスタックにプッシュします。

lua_pushnumber

c
// [-0, +1, -]
void lua_pushnumber (lua_State *L, lua_Number n);

nの数値をスタックにプッシュします。

lua_pushstring

c
// [-0, +1, m]
void lua_pushstring (lua_State *L, const char *s);

sが指すゼロ終了文字列をスタックにプッシュします。Luaは与えられた文字列の内部コピーを作成(または再利用)しますので、関数が戻った直後にsのメモリを解放または再利用できます。文字列に組み込みのゼロを含むことはできず、最初のゼロで終了すると見なされます。

lua_pushthread

c
// [-0, +1, -]
int lua_pushthread (lua_State *L);

Lによって表されるスレッドをスタックにプッシュします。このスレッドがそのステートのメインスレッドであれば1を返します。

lua_pushvalue

c
// [-0, +1, -]
void lua_pushvalue (lua_State *L, int index);

指定された有効なインデックスにある要素のコピーをスタックにプッシュします。

lua_pushvfstring

c
// [-0, +1, m]
const char *lua_pushvfstring (lua_State *L, const char *fmt, va_list argp);

lua_pushfstringと同等ですが、可変個の引数の代わりにva_listを受け取ります。

lua_rawequal

c
// [-0, +0, -]
int lua_rawequal (lua_State *L, int index1, int index2);

許容されるインデックスindex1index2の2つの値が原始的に等しい(つまり、メタメソッドを呼び出さずに)場合は1を返し、そうでなければ0を返します。いずれかのインデックスが無効である場合も0を返します。

lua_rawget

c
// [-1, +1, -]
void lua_rawget (lua_State *L, int index);

lua_gettableに似ていますが、メタメソッドを使用せずに生のアクセスを行います。

lua_rawgeti

c
// [-0, +1, -]
void lua_rawgeti (lua_State *L, int index, int n);

指定された有効なインデックスにある値tt[n]をスタックにプッシュします。アクセスは生のもので、メタメソッドは呼び出されません。

lua_rawset

c
// [-2, +0, m]
void lua_rawset (lua_State *L, int index);

lua_settableに似ていますが、メタメソッドを使用せずに生の割り当てを行います。

lua_rawseti

c
// [-1, +0, m]
void lua_rawseti (lua_State *L, int index, int n);

与えられた有効なインデックスにある値tで、t[n] = vと同等の操作を行います。ここでvはスタックのトップにある値です。

この関数はスタックから値をポップします。割り当ては生のもので、メタメソッドは呼び出されません。

lua_Reader

c
typedef const char * (*lua_Reader) (lua_State *L, void *data, size_t *size);

lua_loadによって使用されるリーダー関数です。別のチャンクの部分が必要になるたびに、lua_loadはそのデータパラメータとともにリーダーを呼び出します。リーダーはチャンクの新しい部分を含むメモリブロックへのポインタを返し、sizeをブロックサイズに設定する必要があります。ブロックは、リーダー関数が再度呼び出されるまで存在する必要があります。チャンクの終わりを示すには、リーダーはNULLを返すか、sizeをゼロに設定する必要があります。リーダー関数はゼロより大きい任意のサイズの部分を返すことができます。

lua_register

c
// [-0, +0, e]
void lua_register (lua_State *L, const char *name, lua_CFunction f);

C関数fをグローバル名nameの新しい値として設定します。マクロとして定義されています:

c
#define lua_register(L,n,f) \
           (lua_pushcfunction(L, f), lua_setglobal(L, n))

lua_remove

c
// [-1, +0, -]
void lua_remove (lua_State *L, int index);

指定された有効なインデックスの要素を削除し、このインデックスより上の要素を下にシフトしてギャップを埋めます。擬似インデックスでは呼び出せません。なぜなら、擬似インデックスは実際のスタック位置ではないからです。

lua_replace

c
// [-1, +0, -]
void lua_replace (lua_State *L, int index);

トップ要素を指定された位置に移動し(ポップします)、他の要素をシフトせずに(したがって、指定された位置の値を置き換えます)。

lua_resume

c
// [-?, +?, -]
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

c
// [-0, +0, -]
void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);

指定されたステートのアロケータ関数をユーザーデータudを持つfに変更します。

lua_setfenv

c
// [-1, +0, -]
int lua_setfenv (lua_State *L, int index);

スタックからテーブルをポップし、指定されたインデックスの値の新しい環境として設定します。指定されたインデックスの値が関数、スレッド、またはユーザーデータでない場合、lua_setfenvは0を返します。それ以外の場合は1を返します。

lua_setfield

c
// [-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

c
// [-1, +0, e]
void lua_setglobal (lua_State *L, const char *name);

スタックから値をポップし、それをグローバル名の新しい値として設定します。マクロとして定義されています:

c
#define lua_setglobal(L,s)   lua_setfield(L, LUA_GLOBALSINDEX, s)

lua_setmetatable

c
// [-1, +0, -]
int lua_setmetatable (lua_State *L, int index);

スタックからテーブルをポップし、指定された有効なインデックスの値の新しいメタテーブルとして設定します。

lua_settable

c
// [-2, +0, e]
void lua_settable (lua_State *L, int index);

t[k] = vと同等の操作を行います。ここでtは与えられた有効なインデックスでの値、vはスタックのトップにあり、kはトップの直下にある値です。

この関数はキーと値の両方をスタックからポップします。Luaと同様に、この関数は"newindex"イベントのメタメソッドを起動する可能性があります(§2.8を参照)。

lua_settop

c
// [-?, +?, -]
void lua_settop (lua_State *L, int index);

任意の有効なインデックス、または0を受け付け、スタックのトップをこのインデックスに設定します。新しいトップが古いものより大きい場合、新しい要素はnilで埋められます。インデックスが0の場合、すべてのスタック要素が削除されます。

lua_State

c
typedef struct lua_State lua_State;

Luaインタープリタの全状態を保持する不透明な構造体です。Luaライブラリは完全に再入可能であり、グローバル変数を持っていません。状態に関するすべての情報はこの構造体に保持されます。

この状態へのポインタは、ライブラリのすべての関数に対して最初の引数として渡されなければなりません。ただし、lua_newstateは除きます。この関数は最初からLuaの状態を作成します。

lua_status

c
// [-0, +0, -]
int lua_status (lua_State *L);

スレッドLの状態を返します。

状態は、通常のスレッドの場合は0、スレッドがエラーで実行を終了した場合はエラーコード、スレッドが中断されている場合はLUA_YIELDになります。

lua_toboolean

c
// [-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

c
// [-0, +0, -]
lua_CFunction lua_tocfunction (lua_State *L, int index);

与えられた有効なインデックスの値をC関数に変換します。その値はC関数でなければならず、そうでない場合はNULLを返します。

lua_tointeger

c
// [-0, +0, -]
lua_Integer lua_tointeger (lua_State *L, int index);

与えられた有効なインデックスでのLua値を符号付き整数型lua_Integerに変換します。Lua値は数値または数値に変換可能な文字列でなければなりません(§2.2.1を参照);そうでない場合、lua_tointegerは0を返します。

数値が整数でない場合、それは特定されていない何らかの方法で切り捨てられます。

lua_tolstring

c
// [-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

c
// [-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

c
// [-0, +0, -]
const void *lua_topointer (lua_State *L, int index);

与えられた有効なインデックスの値を一般的なCポインタ(void*)に変換します。値はユーザーデータ、テーブル、スレッド、または関数である可能性があります;そうでない場合、lua_topointerはNULLを返します。異なるオブジェクトは異なるポインタを与えます。ポインタを元の値に戻す方法はありません。

通常、この関数はデバッグ情報用にのみ使用されます。

lua_tostring

c
// [-0, +0, m]
const char *lua_tostring (lua_State *L, int index);

lenがNULLに等しいlua_tolstringと同等です。

lua_tothread

c
// [-0, +0, -]
lua_State *lua_tothread (lua_State *L, int index);

与えられた有効なインデックスの値をLuaスレッド(lua_State*として表される)に変換します。この値はスレッドでなければならず、そうでない場合、関数はNULLを返します。

lua_touserdata

c
// [-0, +0, -]
void *lua_touserdata (lua_State *L, int index);

与えられた有効なインデックスの値が完全なユーザーデータの場合、そのブロックアドレスを返します。値がライトユーザーデータの場合、そのポインタを返します。それ以外の場合はNULLを返します。

lua_type

c
// [-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

c
// [-0, +0, -]
const char *lua_typename  (lua_State *L, int tp);

tpでエンコードされた型の名前を返します。tplua_typeによって返された値でなければなりません。

lua_Writer

c
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

c
// [-?, +?, -]
void lua_xmove (lua_State *from, lua_State *to, int n);

同じグローバル状態の異なるスレッド間で値を交換します。

この関数はfromのスタックからn個の値をポップし、それらをtoのスタックにプッシュします。

lua_yield

c
// [-?, +?, -]
int lua_yield  (lua_State *L, int nresults);

コルーチンを中断します。

この関数はC関数のリターン式としてのみ呼び出されるべきです:

c
return lua_yield (L, nresults);

C関数がこの方法でlua_yieldを呼び出すと、実行中のコルーチンはその実行を中断し、このコルーチンを開始したlua_resumeの呼び出しが戻ります。nresultsパラメータは、lua_resumeへの結果としてスタックから渡される値の数です。

3.8 – デバッグインターフェース

Luaには組み込みのデバッグ機能はありません。代わりに、関数やフックを通じて特別なインターフェースを提供しています。このインターフェースは、インタープリターからの「内部情報」を必要とするさまざまな種類のデバッガー、プロファイラー、その他のツールの構築を可能にします。

lua_Debug

c
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

c
// [-0, +0, -]
lua_Hook lua_gethook (lua_State *L);

現在のフック関数を返します。

lua_gethookcount

c
// [-0, +0, -]
int lua_gethookcount (lua_State *L);

現在のフックカウントを返します。

lua_gethookmask

c
// [-0, +0, -]
int lua_gethookmask (lua_State *L);

現在のフックマスクを返します。

lua_getinfo

c
// [-(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がどの行で定義されたかを知るには、次のコードを書くことができます:

c
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': namenamewhatフィールドを記入します。
  • 'S': sourceshort_srclinedefinedlastlinedefined、およびwhatフィールドを記入します。
  • 'l': currentlineフィールドを記入します。
  • 'u': nupsフィールドを記入します。
  • 'f': 与えられたレベルで実行中の関数をスタックにプッシュします。
  • 'L': 関数で有効な行の番号がインデックスであるテーブルをスタックにプッシュします。(有効な行とは、コードが関連付けられている行、つまり、ブレークポイントを置くことができる行です。無効な行には空行やコメントが含まれます。)

この関数はエラーが発生した場合(例えば、whatで無効なオプションがある場合)に0を返します。

lua_getlocal

c
// [-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

c
// [-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

c
// [-0, +(0|1), -]
const char *lua_getupvalue (lua_State *L, int funcindex, int n);

クロージャのアップバリューについての情報を取得します。(Lua関数の場合、アップバリューは関数が使用する外部のローカル変数であり、結果としてクロージャに含まれます。)lua_getupvalueはアップバリューのインデックスnを取得し、アップバリューの値をスタックにプッシュし、その名前を返します。funcindexはスタック内のクロージャを指します。(アップバリューには特定の順序がなく、関数全体を通してアクティブです。したがって、任意の順序で番号付けされます。)

インデックスがアップバリューの数を超える場合、NULL(何もプッシュせず)を返します。C関数の場合、この関数はすべてのアップバリューの名前として空の文字列""を使用します。

lua_Hook

c
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を呼び出さなければなりません。戻りイベントの場合、eventLUA_HOOKRET(通常の値)またはLUA_HOOKTAILRETになります。後者の場合、Luaはテールコールを行った関数からの戻りをシミュレートしています。この場合、lua_getinfoを呼び出すことは無意味です。

Luaがフックを実行している間、他のフックへの呼び出しは無効になります。したがって、フックがLuaを呼び出して関数やチャンクを実行する場合、この実行はフックへの呼び出しなしで行われます。

lua_sethook

c
// [-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引数は、maskLUA_MASKCOUNTを含む場合にのみ意味があります。各イベントについて、フックは以下に説明されるように呼び出されます:

  • コールフック:インタプリタが関数を呼び出すときに呼び出されます。フックはLuaが新しい関数に入った直後、関数がその引数を得る前に呼び出されます。
  • 戻りフック:インタプリタが関数から戻るときに呼び出されます。フックはLuaが関数を離れる直前に呼び出されます。関数によって返される値にアクセスすることはできません。
  • ラインフック:インタプリタが新しいコード行の実行を開始しようとするとき、またはコード内で後戻りするとき(同じ行に戻る場合でも)に呼び出されます。(このイベントはLuaがLua関数を実行している間のみ発生します。)
  • カウントフック:インタプリタがカウント命令ごとに実行するときに呼び出されます。(このイベントはLuaがLua関数を実行している間のみ発生します。)

フックはmaskをゼロに設定することで無効になります。

lua_setlocal

c
// [-(0|1), +0, -]
const char *lua_setlocal (lua_State *L, lua_Debug *ar, int n);

与えられたアクティベーションレコードのローカル変数の値を設定します。パラメータarnlua_getlocallua_getlocalを参照)と同じです。lua_setlocalはスタックのトップにある値を変数に割り当て、その名前を返します。また、スタックから値をポップします。

インデックスがアクティブなローカル変数の数を超える場合は、NULL(何もポップせず)を返します。

lua_setupvalue

c
// [-(0|1), +0, -]
const char *lua_setupvalue (lua_State *L, int funcindex, int n);

クロージャのアップバリューの値を設定します。スタックのトップにある値をアップバリューに割り当て、その名前を返します。値もスタックからポップします。パラメータfuncindexnlua_getupvaluelua_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

c
// [-0, +0, m]
void luaL_addchar (luaL_Buffer *B, char c);

文字cをバッファBに追加します(luaL_Bufferを参照)。

luaL_addlstring

c
// [-0, +0, m]
void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l);

長さlの文字列sをバッファBに追加します(luaL_Bufferを参照)。文字列には組み込みのゼロを含むことができます。

luaL_addsize

c
// [-0, +0, m]
void luaL_addsize (luaL_Buffer *B, size_t n);

以前にバッファ領域にコピーされた長さnの文字列をバッファBに追加します(luaL_Bufferを参照)。

luaL_addstring

c
// [-0, +0, m]
void luaL_addstring (luaL_Buffer *B, const char *s);

ゼロ終端文字列sをバッファBに追加します(luaL_Bufferを参照)。文字列には組み込みのゼロを含むことはできません。

luaL_addvalue

c
[-1, +0, m]
void luaL_addvalue (luaL_Buffer *B);

スタックのトップにある値をバッファBに追加します(luaL_Bufferを参照)。値をポップします。

これは文字列バッファに対して呼び出すことができ(そして呼び出す必要がある)唯一の関数です。バッファに追加する値がスタック上に余分に存在する必要があります。

luaL_argcheck

c
// [-0, +0, v]
void luaL_argcheck (lua_State *L, int cond, int narg, const char *extramsg);

condが真であることを確認します。そうでない場合、以下のメッセージでエラーを発生させます。ここでfuncはコールスタックから取得されます:

txt
<func>への引数#<narg>が不正です(<extramsg>)

luaL_argerror

c
// [-0, +0, v]
int luaL_argerror (lua_State *L, int narg, const char *extramsg);

以下のメッセージでエラーを発生させます。ここでfuncはコールスタックから取得されます:

txt
<func>への引数#<narg>が不正です(<extramsg>)

この関数は決して返りませんが、C関数内でreturn luaL_argerror(args)として使用するのが一般的な慣習です。

luaL_Buffer

c
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

c
// [-0, +0, -]
void luaL_buffinit (lua_State *L, luaL_Buffer *B);

バッファBを初期化します。この関数は空間を割り当てません。バッファは変数として宣言される必要があります(luaL_Bufferを参照)。

luaL_callmeta

c
// [-0, +(0|1), e]
int luaL_callmeta (lua_State *L, int obj, const char *e);

メタメソッドを呼び出します。

インデックスobjのオブジェクトにメタテーブルがあり、このメタテーブルにフィールドeがある場合、この関数はこのフィールドを呼び出し、オブジェクトを唯一の引数として渡します。この場合、この関数は1を返し、スタックに呼び出しによって返された値をプッシュします。メタテーブルやメタメソッドがない場合、この関数は0を返します(スタックに値をプッシュせず)。

luaL_checkany

c
// [-0, +0, v]
void luaL_checkany (lua_State *L, int narg);

位置nargに任意の型(nilを含む)の引数があるかどうかをチェックします。

luaL_checkint

c
// [-0, +0, v]
int luaL_checkint (lua_State *L, int narg);

関数の引数nargが数値であるか確認し、その数値をintにキャストして返します。

luaL_checkinteger

c
// [-0, +0, v]
lua_Integer luaL_checkinteger (lua_State *L, int narg);

関数の引数nargが数値であるか確認し、その数値をlua_Integerにキャストして返します。

luaL_checklong

c
// [-0, +0, v]
long luaL_checklong (lua_State *L, int narg);

関数の引数nargが数値であるか確認し、その数値をlongにキャストして返します。

luaL_checklstring

c
// [-0, +0, v]
const char *luaL_checklstring (lua_State *L, int narg, size_t *l);

関数の引数nargが文字列であるか確認し、その文字列を返します。lNULLでなければ、その文字列の長さを*lに設定します。

この関数は結果を得るためにlua_tolstringを使用するため、その関数のすべての変換と注意点がここに適用されます。

luaL_checknumber

c
// [-0, +0, v]
lua_Number luaL_checknumber (lua_State *L, int narg);

関数の引数nargが数値であるか確認し、その数値を返します。

luaL_checkoption

c
// [-0, +0, v]
int luaL_checkoption (lua_State *L, int narg, const char *def, const char *const lst[]);

関数の引数nargが文字列であるか確認し、その文字列を配列lst(NULLで終了する必要があります)で検索します。文字列が見つかった配列内のインデックスを返します。引数が文字列でない場合や文字列が見つからない場合はエラーを発生させます。

defNULLでない場合、この関数は引数nargが存在しない場合やnilである場合にデフォルト値としてdefを使用します。

これは文字列をCの列挙型にマッピングするのに便利な関数です(Luaライブラリでは、オプションを選択するために数値の代わりに文字列を使用するのが通常の慣習です)。

luaL_checkstack

c
// [-0, +0, v]
void luaL_checkstack (lua_State *L, int sz, const char *msg);

スタックサイズをtop + sz要素まで増やし、スタックをそのサイズまで増やせない場合にはエラーを発生させます。msgはエラーメッセージに追加するテキストです。

luaL_checkstring

c
// [-0, +0, v]
const char *luaL_checkstring (lua_State *L, int narg);

関数の引数nargが文字列であるか確認し、その文字列を返します。

この関数は結果を得るためにlua_tolstringを使用するので、その関数のすべての変換と注意点がここに適用されます。

luaL_checktype

c
// [-0, +0, v]
void luaL_checktype (lua_State *L, int narg, int t);

関数の引数nargの型がtであるか確認します。tの型のエンコーディングについてはlua_typeを参照してください。

luaL_checkudata

c
// [-0, +0, v]
void *luaL_checkudata (lua_State *L, int narg, const char *tname);

関数の引数nargが型tnameのユーザーデータであるか確認します(luaL_newmetatableを参照)。

luaL_dofile

c
// [-0, +?, m]
int luaL_dofile (lua_State *L, const char *filename);

指定されたファイルをロードして実行します。以下のマクロとして定義されています:

c
(luaL_loadfile(L, filename) || lua_pcall(L, 0, LUA_MULTRET, 0))

エラーがなければ0を返し、エラーがある場合は1を返します。

luaL_dostring

c
// [-0, +?, m]
int luaL_dostring (lua_State *L, const char *str);

指定された文字列をロードして実行します。以下のマクロとして定義されています:

c
(luaL_loadstring(L, str) || lua_pcall(L, 0, LUA_MULTRET, 0))

エラーがなければ0を返し、エラーがある場合は1を返します。

luaL_error

c
// [-0, +0, v]
int luaL_error (lua_State *L, const char *fmt, ...);

エラーを発生させます。エラーメッセージの形式はfmtと追加の引数によって指定され、lua_pushfstringのルールに従います。この関数はエラーが発生したファイル名と行番号をメッセージの最初に追加します(この情報が利用可能な場合)。

この関数は戻り値を返しませんが、C関数内でreturn luaL_error(args);として使用するのが一般的です。

luaL_getmetafield

c
// [-0, +(0|1), m]
int luaL_getmetafield (lua_State *L, int obj, const char *e);

インデックスobjのオブジェクトのメタテーブルからフィールドeをスタックにプッシュします。オブジェクトにメタテーブルがない場合、またはメタテーブルにこのフィールドがない場合、0を返し何もプッシュしません。

luaL_getmetatable

c
// [-0, +1, -]
void luaL_getmetatable (lua_State *L, const char *tname);

レジストリ内のtname名で関連付けられたメタテーブルをスタックにプッシュします(luaL_newmetatableを参照)。

luaL_gsub

c
// [-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

c
// [-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

c
// [-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

c
// [-0, +1, m]
int luaL_loadstring (lua_State *L, const char *s);

文字列をLuaチャンクとしてロードします。この関数はlua_loadを使用して、ゼロ終端文字列s内のチャンクをロードします。

この関数はlua_loadと同じ結果を返します。

また、lua_loadと同様に、この関数はチャンクをロードするだけで、実行はしません。

luaL_newmetatable

c
// [-0, +1, m]
int luaL_newmetatable (lua_State *L, const char *tname);

レジストリにtnameというキーが既に存在する場合、0を返します。そうでない場合、ユーザーデータのメタテーブルとして使用される新しいテーブルを作成し、tnameのキーでレジストリに追加し、1を返します。

どちらの場合も、レジストリ内のtnameに関連付けられた最終的な値をスタックにプッシュします。

luaL_newstate

c
// [-0, +0, -]
lua_State *luaL_newstate (void);

新しいLuaステートを作成します。標準のC realloc関数に基づくアロケータを使用してlua_newstateを呼び出し、致命的なエラーが発生した場合に標準エラー出力にエラーメッセージを出力するパニック関数(lua_atpanicを参照)を設定します。

新しいステートを返すか、メモリ割り当てエラーがある場合はNULLを返します。

luaL_openlibs

c
// [-0, +0, m]
void luaL_openlibs (lua_State *L);

指定されたステートにすべての標準Luaライブラリを開きます。

luaL_optint

c
// [-0, +0, v]
int luaL_optint (lua_State *L, int narg, int d);

関数の引数nargが数値の場合、この数値をint型にキャストして返します。この引数が存在しないかnilの場合はdを返します。そうでない場合、エラーを発生させます。

luaL_optinteger

c
// [-0, +0, v]
lua_Integer luaL_optinteger (lua_State *L, int narg, lua_Integer d);

関数の引数nargが数値の場合、その数値をlua_Integer型にキャストして返します。この引数が欠けている場合やnilの場合は、dを返します。それ以外の場合はエラーを発生させます。

luaL_optlong

c
// [-0, +0, v]
long luaL_optlong (lua_State *L, int narg, long d);

関数の引数nargが数値の場合、その数値をlong型にキャストして返します。この引数が欠けている場合やnilの場合は、dを返します。それ以外の場合はエラーを発生させます。

luaL_optlstring

c
// [-0, +0, v]
const char *luaL_optlstring (lua_State *L, int narg, const char *d, size_t *l);

関数の引数nargが文字列の場合、その文字列を返します。この引数が欠けている場合やnilの場合は、dを返します。それ以外の場合はエラーを発生させます。

lNULLではない場合、結果の長さで*lを埋めます。

luaL_optnumber

c
// [-0, +0, v]
lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number d);

関数の引数nargが数値の場合、その数値を返します。この引数が欠けている場合やnilの場合は、dを返します。それ以外の場合はエラーを発生させます。

luaL_optstring

c
// [-0, +0, v]
const char *luaL_optstring (lua_State *L, int narg, const char *d);

関数の引数nargが文字列の場合、その文字列を返します。この引数が欠けている場合やnilの場合は、dを返します。それ以外の場合はエラーを発生させます。

luaL_prepbuffer

c
// [-0, +0, -]
char *luaL_prepbuffer (luaL_Buffer *B);

バッファBに追加される文字列をコピーするための、サイズLUAL_BUFFERSIZEのスペースへのアドレスを返します(luaL_Bufferを参照)。このスペースに文字列をコピーした後、実際にバッファに追加するためにはluaL_addsizeを文字列のサイズで呼び出す必要があります。

luaL_pushresult

c
// [-?, +1, m]
void luaL_pushresult (luaL_Buffer *B);

バッファBの使用を終了し、最終的な文字列をスタックのトップに残します。

luaL_ref

c
// [-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

c
typedef struct luaL_Reg {
  const char *name;
  lua_CFunction func;
} luaL_Reg;

luaL_registerによって登録される関数の配列の型です。nameは関数名で、funcは関数へのポインタです。luaL_Regの配列は、namefuncの両方がNULLであるセンチネルエントリで終了する必要があります。

luaL_register

c
// [-(0|1), +1, m]
void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l);

ライブラリをオープンします。

libnameNULLに等しい場合、単にリストl内のすべての関数(luaL_Regを参照)をスタックのトップにあるテーブルに登録します。

libnameが非nullで呼び出された場合、luaL_registerは新しいテーブルtを作成し、グローバル変数libnameの値として設定し、package.loaded[libname]の値として設定し、リストlのすべての関数をそれに登録します。package.loaded[libname]や変数libnameにテーブルがある場合は、新しいテーブルを作成する代わりにこのテーブルを再利用します。

いずれの場合も、関数はテーブルをスタックのトップに残します。

luaL_typename

c
// [-0, +0, -]
const char *luaL_typename (lua_State *L, int index);

指定されたインデックスの値の型の名前を返します。

luaL_typerror

c
// [-0, +0, v]
int luaL_typerror (lua_State *L, int narg, const char *tname);

以下のようなメッセージでエラーを生成します:

txt
location: bad argument narg to 'func' (tname expected, got rt)

ここでlocationluaL_whereによって生成され、funcは現在の関数の名前であり、rtは実際の引数の型名です。

luaL_unref

c
// [-0, +0, -]
void luaL_unref (lua_State *L, int t, int ref);

インデックスtのテーブルから参照refを解放します(luaL_refを参照)。エントリはテーブルから削除されるので、参照されたオブジェクトは回収されることができます。参照refも再利用のために解放されます。

refLUA_NOREFまたはLUA_REFNILの場合、luaL_unrefは何も行いません。

luaL_where

c
// [-0, +1, m]
void luaL_where (lua_State *L, int lvl);

呼び出しスタックのレベルlvlでの制御の現在位置を識別する文字列をスタックにプッシュします。通常、この文字列は以下のフォーマットを持っています:

txt
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つの値を返し、次の構成

lua
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に似ていますが、指定された文字列からチャンクを取得します。

指定された文字列を読み込んで実行するには、次の慣用句を使用します:

lua
assert(loadstring(s))()

省略された場合、chunknameは指定された文字列にデフォルト設定されます。

next (table [, index])

プログラムがテーブルの全てのフィールドをトラバースすることを可能にします。第一引数はテーブルで、第二引数はこのテーブル内のインデックスです。nextはテーブルの次のインデックスとそれに関連付けられた値を返します。第二引数にnilを使用して呼び出された場合、nextは初期インデックスとそれに関連付けられた値を返します。最後のインデックスで呼び出された場合、または空のテーブルでnilを使用して呼び出された場合、nextnilを返します。第二引数が省略された場合、それはnilと解釈されます。特に、next(t)を使用してテーブルが空かどうかを確認できます。

インデックスが列挙される順序は、数値インデックスであっても指定されていません。(数値順でテーブルをトラバースするには、数値のforまたはipairs関数を使用してください。)

トラバース中にテーブルに存在しないフィールドに値を割り当てる場合、nextの動作は未定義です。ただし、既存のフィールドを修正することはできます。特に、既存のフィールドをクリアすることができます。

pairs (t)

3つの値を返します:next関数、テーブルt、そしてnilです。そのため、次の構成

lua
for k,v in pairs(t) do body end

はテーブルtの全てのキーと値のペアをイテレートします。

テーブルのトラバース中にテーブルを修正する際の注意点については、next関数を参照してください。

pcall (f, arg1, ···)

関数fを保護モードで与えられた引数で呼び出します。これは、f内の任意のエラーが伝播されないことを意味します。代わりに、pcallはエラーをキャッチし、ステータスコードを返します。最初の結果はステータスコード(真偽値)であり、エラーなしに呼び出しが成功するとtrueになります。その場合、pcallはこの最初の結果の後に、呼び出しからの全ての結果を返します。エラーが発生した場合、pcallfalseとエラーメッセージを返します。

任意の数の引数を受け取り、それらの値をtostring関数を使用して文字列に変換し、標準出力に出力します。printは整形された出力を意図したものではなく、通常はデバッグのために値をすばやく表示するためだけに使用されます。整形された出力にはstring.formatを使用してください。

rawequal (v1, v2)

v1v2と等しいかどうかをチェックし、メタメソッドを呼び出さずに真偽値を返します。

rawget (table, index)

メタメソッドを呼び出さずにtable[index]の実際の値を取得します。tableはテーブルでなければならず、indexは任意の値です。

rawset (table, index, value)

メタメソッドを呼び出さずにtable[index]の実際の値をvalueに設定します。tableはテーブルでなければならず、indexnil以外の任意の値であり、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からのみ可能です。)metatablenilの場合、指定されたテーブルのメタテーブルを削除します。元のメタテーブルに"__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"フィールドがある場合、tostringeを引数として対応する値を呼び出し、その呼び出しの結果をその結果として使用します。

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に似ていますが、新しいエラーハンドラを設定できます。

xpcallerrをエラーハンドラとして使用し、保護モードで関数fを呼び出します。f内の任意のエラーは伝播されません。代わりに、xpcallはエラーをキャッチし、元のエラーオブジェクトでerr関数を呼び出し、ステータスコードを返します。最初の結果はステータスコード(真偽値)であり、エラーなしで呼び出しが成功した場合はtrueです。この場合、xpcallはこの最初の結果の後に、呼び出しからのすべての結果も返します。エラーが発生した場合、xpcallfalseerrからの結果を返します。

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つをグローバル環境で直接エクスポートします:requiremodule。その他のものはテーブルpackageでエクスポートされます。

module (name [, ...])

モジュールを作成します。package.loaded[name]にテーブルがある場合、このテーブルがモジュールになります。そうでない場合、指定された名前のグローバルテーブルtがあれば、このテーブルがモジュールになります。そうでなければ、新しいテーブルtを作成し、それをグローバル名とpackage.loaded[name]の値として設定します。この関数はまた、t._NAMEを与えられた名前で、t._Mをモジュール(t自身)で、t._PACKAGEをパッケージ名(最後のコンポーネントを除いた完全なモジュール名)で初期化します。最後に、modulerequiretを返すように、現在の関数の新しい環境とpackage.loaded[name]の新しい値としてtを設定します。

名前が複合名(つまり、ドットで区切られたコンポーネントを持つもの)の場合、moduleはそれぞれのコンポーネントに対してテーブルを作成(または既に存在する場合は再利用)します。例えば、名前がa.b.cであれば、moduleはモジュールテーブルをグローバルaのフィールドbのフィールドcに格納します。

この関数は、モジュール名の後にオプションを受け取ることができ、各オプションはモジュールに適用される関数です。

require (modname)

指定されたモジュールをロードします。この関数はまずpackage.loadedテーブルを調べて、modnameが既にロードされているかどうかを判断します。もしロードされている場合は、package.loaded[modname]に格納された値をrequireが返します。そうでない場合、モジュールのローダーを見つけるために試みます。

ローダーを見つけるために、requirepackage.loaders配列に従います。この配列を変更することで、requireがモジュールをどのように探すかを変更できます。以下の説明は、package.loadersのデフォルト設定に基づいています。

最初にrequirepackage.preload[modname]を問い合わせます。値があれば、この値(関数であるべきです)がローダーです。そうでなければ、requirepackage.pathに格納されたパスを使ってLuaローダーを探します。それも失敗した場合は、package.cpathに格納されたパスを使ってCローダーを探します。それも失敗した場合は、オールインワンローダー(package.loadersを参照)を試みます。

ローダーが見つかったら、requireは単一の引数modnameを使用してローダーを呼び出します。ローダーが何か値を返す場合、requireはその返された値をpackage.loaded[modname]に割り当てます。ローダーが値を返さず、package.loaded[modname]に値を割り当てていない場合、requireはこのエントリにtrueを割り当てます。いずれの場合も、requirepackage.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パスが文字列

txt
"./?.lua;./?.lc;/usr/local/?/init.lua"

であれば、モジュールfooのLuaファイルを探す際には、./foo.lua./foo.lc/usr/local/foo/init.luaの順にファイルを開こうとします。

3番目のサーチャーは、変数package.cpathによって与えられたパスを使用してCライブラリとしてローダーを探します。例えば、Cパスが文字列

txt
"./?.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ファミリーと同じルールに従います。唯一の違いは、オプション/修飾子*lLnphがサポートされていないことと、qという追加オプションがあることです。qオプションは、文字列をLuaインタプリターによって安全に読み戻すことができる形式でフォーマットします。文字列は二重引用符で書かれ、文字列の中のすべての二重引用符、改行、組み込みゼロ、バックスラッシュが正しくエスケープされて出力されます。例えば、以下の呼び出し

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

は、以下の文字列を生成します:

txt
"a string with \"quotes\" and \
 new line"

オプションcdEefgGiouXxはすべて数値を引数として期待していますが、qsは文字列を期待しています。

この関数は、qオプションへの引数としての場合を除き、組み込みゼロを含む文字列値を受け入れません。

string.gmatch (s, pattern)

呼び出すたびに、文字列s上でパターンから次のキャプチャを返すイテレータ関数を返します。パターンがキャプチャを指定していない場合、各呼び出しで完全なマッチが生成されます。 例として、以下のループ

lua
s = "hello world from Lua"
for w in string.gmatch(s, "%a+") do
  print(w)
end

は、文字列sからのすべての単語を繰り返し、一行に一つずつ印刷します。次の例は、与えられた文字列からすべてのキー=値のペアをテーブルに収集します:

lua
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であれば、置換は行われません(つまり、元のマッチが文字列に保持されます)。

いくつかの例を挙げます:

lua
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)

文字列snコピーの連結である文字列を返します。

string.reverse (s)

文字列sを反転させた文字列を返します。

string.sub (s, i [, j])

文字列siから始まりjまで続く部分文字列を返します。ijは負の数も可能です。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内のすべての文字の和集合を表すクラスです。文字の範囲は、範囲の終端文字を-で区切ることによって指定できます。上記で説明されたすべてのクラス %xset の要素として使用できます。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のデフォルトはテーブルの長さです。ijより大きい場合、空文字列を返します。

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.stdinio.stdoutio.stderr。入出力ライブラリはこれらのファイルを決して閉じません。

特に明記されていない限り、すべての入出力関数は失敗時にはnilを返し(2番目の結果としてエラーメッセージ、3番目の結果としてシステム依存のエラーコードも返します)、成功時にはnilではない何かの値を返します。

io.close ([file])

file:close()と同等です。ファイルが指定されていない場合、デフォルトの出力ファイルを閉じます。

io.flush ()

デフォルトの出力ファイルに対してfile:flushと同等です。

io.input ([file])

ファイル名が指定された場合、指定されたファイルをテキストモードで開き、そのハンドルをデフォルトの入力ファイルとして設定します。ファイルハンドルが指定された場合、単にこのファイルハンドルをデフォルトの入力ファイルとして設定します。パラメータなしで呼び出された場合、現在のデフォルト入力ファイルを返します。

エラーが発生した場合、この関数はエラーコードを返す代わりにエラーを発生させます。

io.lines ([filename])

指定されたファイル名を読み取りモードで開き、それを呼び出すたびにファイルから新しい行を返すイテレータ関数を返します。したがって、

lua
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])

引数なしで呼び出された場合は現在の時刻を返し、与えられたテーブルによって指定された日付と時刻を表す時刻を返します。このテーブルにはyearmonthdayのフィールドが必要で、hourminsecisdstのフィールドがある場合があります(これらのフィールドの説明については、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 がアクティブな関数の数より大きい数値の場合、getinfonil を返します。

返されるテーブルには、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と呼ばれ、標準配布に含まれています。スタンドアロンインタプリタには、デバッグライブラリを含むすべての標準ライブラリが含まれています。その使用方法は以下の通りです:

sh
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を除いて順番に処理されます。例えば、

sh
lua -e'a=1' -e 'print(a)' script.lua

この呼び出しでは、最初にaを1に設定し、次にaの値('1')を表示し、最後に引数なしでファイルscript.luaを実行します。(ここで$はシェルプロンプトです。プロンプトは異なる場合があります。)

スクリプトの実行を開始する前に、luaはコマンドラインのすべての引数をargというグローバルテーブルに収集します。スクリプト名はインデックス0に格納され、スクリプト名の後の最初の引数はインデックス1に格納され、以下同様に続きます。スクリプト名の前の任意の引数(つまり、インタプリタ名とオプション)は負のインデックスに格納されます。例えば、呼び出し

sh
lua -la b.lua t1 t2

では、インタプリタは最初にファイルa.luaを実行し、次にテーブル

lua
arg = { [-2] = "lua", [-1] = "-la",
        [0] = "b.lua",
        [1] = "t1", [2] = "t2" }

を作成し、最後にファイルb.luaを実行します。スクリプトは引数arg[1]arg[2]、...で呼び出されます。また、可変長引数式...を使用してこれらの引数にアクセスすることも

対話モードでは、不完全な文を入力すると、インタープリタは異なるプロンプトを表示してその完了を待ちます。

グローバル変数_PROMPTが文字列を含む場合、その値がプロンプトとして使用されます。同様に、グローバル変数_PROMPT2が文字列を含む場合、その値が不完全な文の際に表示されるセカンダリプロンプトとして使用されます。したがって、これらのプロンプトはコマンドラインやLuaプログラム内で_PROMPTに割り当てることによって直接変更できます。次の例を参照してください:

sh
lua -e"_PROMPT='myprompt> '" -i

(外側の引用符はシェル用、内側の引用符はLua用です。)対話モードに入るための-iの使用に注意してください。さもなければ、プログラムは_PROMPTへの割り当ての直後に静かに終了します。

UnixシステムでLuaをスクリプトインタプリタとして使用できるようにするため、スタンドアロンインタープリタは、チャンクの最初の行が#で始まる場合、その行をスキップします。したがって、Luaスクリプトはchmod +x#!形式を使用して実行可能プログラムにすることができます:

txt
#!/usr/local/bin/lua

(もちろん、Luaインタープリタの場所はマシンによって異なる場合があります。luaがPATH内にある場合、

txt
#!/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.gfindstring.gmatchに名前が変更されました。(luaconf.hのコンパイル時オプションLUA_COMPAT_GFINDを参照してください。)
  • string.gsubが第三引数に関数を持つ場合、この関数がnilまたはfalseを返すと、置換文字列は空の文字列ではなく、全体の一致部分になります。
  • 関数table.setnは非推奨となりました。関数table.getnは新しい長さ演算子(#)に対応しています。関数の代わりに演算子を使用してください。(luaconf.hのコンパイル時オプションLUA_COMPAT_GETNを参照してください。)
  • 関数loadlibpackage.loadlibに名前が変更されました。(luaconf.hのコンパイル時オプションLUA_COMPAT_LOADLIBを参照してください。)
  • 関数math.modmath.fmodに名前が変更されました。(luaconf.hのコンパイル時オプションLUA_COMPAT_MODを参照してください。)
  • 関数table.foreachtable.foreachiは非推奨となりました。pairsまたはipairsを使用したforループを代わりに使用できます。
  • 新しいモジュールシステムにより、関数requireに大きな変更がありました。ただし、新しい動作は古い動作とほとんど互換性がありますが、requireLUA_PATHではなくpackage.pathからパスを取得します。
  • 関数collectgarbageは異なる引数を持ちます。関数gcinfoは非推奨となり、代わりにcollectgarbage("count")を使用してください。

7.3 – APIの変更点

  • ライブラリを開くためのluaopen_*関数は、通常のC関数のように直接呼び出すことができません。Lua関数のようにLuaを通じて呼び出す必要があります。
  • 関数lua_openは、ユーザーがメモリ割り当て関数を設定できるようにlua_newstateに置き換えられました。標準ライブラリのluaL_newstateを使用して、reallocに基づく標準割り当て関数を持つ状態を作成できます。
  • 補助ライブラリからの関数luaL_getnluaL_setnは非推奨です。luaL_getnの代わりにlua_objlenを使用し、luaL_setnの代わりに何も使用しないでください。
  • 関数luaL_openlibluaL_registerに置き換えられました。
  • 関数luaL_checkudataは、与えられた値が期待されるタイプのユーザーデータでない場合にエラーを投げるようになりました。(Lua 5.0ではNULLを返しました。)

8 – Luaの完全な構文

以下は拡張BNFで表されたLuaの完全な構文です。(演算子の優先順位については記述されていません。)

txt
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 | `#´