Lua/チュートリアル
Luaは、軽量で高速なスクリプト言語であり、広く使われているプログラミング言語の一つです。Luaは、簡単に学べる言語でありながら、多くの機能が備わっており、ゲーム開発やWebアプリケーション、組み込みシステムなど、様々な分野で使われています。
本チュートリアルでは、Luaの基礎的な構文や機能について説明し、Luaを使ったプログラミングについての知識を身に付けることを目的としています。本チュートリアルは、初心者から中級者までを対象にしており、Luaの基礎から始めて、徐々に応用的な内容に移っていきます。
Luaの学習は、プログラミング初心者にも取り組みやすく、さまざまなアプリケーションで活用できることから、将来性が高く注目を集めています。本チュートリアルを通して、Luaの基礎を学び、Luaを使ったプログラミングの魅力に触れていただければ幸いです。
イントロダクション

Luaは、1993年にブラジルで開発された軽量で高速なスクリプト言語で、オープンソースであることが特徴です。Luaは、スクリプト言語としては比較的小さく、C言語で書かれているため、高速でメモリ効率が良いという特徴があります。
イントロダクション

Luaの特徴は、軽量で高速なことや、C言語との親和性が高いことに加え、以下のようなものが挙げられます。
イントロダクション

Luaは、以下のような分野で使われています。
イントロダクション

Luaは、その小ささや高速性、拡張性、埋め込み性などの特徴から、様々な分野で利用されています。
インストールとセットアップ

Luaは、公式サイト( https://www.lua.org/download.html )から、ソースコードやバイナリファイルをダウンロードすることができます。 また、一部のLinuxディストリビューションやBSD系UNIXでは、パッケージマネージャを利用して簡単にインストールすることができます。
インストールとセットアップ

インストールが完了したら、コマンドラインから以下のように入力することで、Luaの対話モードを起動することができます。
インストールとセットアップ

対話モードは、コマンドラインから一行ずつLuaのコードを入力して、即座に評価することができます。
インストールとセットアップ

また、Luaのプログラムをファイルに保存して実行することもできます。例えば、以下のようなスクリプトファイルを作成し、"hello.lua"という名前で保存します。
インストールとセットアップ

そして、コマンドラインから以下のように入力することで、スクリプトを実行することができます。
インストールとセットアップ

Luaのプログラムを書くためには、テキストエディターが必要です。 多くのテキストエディターがLuaのシンタックスハイライトをサポートしていますが、特におすすめなのは、ZeroBrane StudioやVisual Studio Codeなどの、Lua開発に特化したエディターです。 これらのエディターには、デバッグ機能やコード補完機能など、開発を効率化する機能が多数備わっています。
変数とデータ型

Luaでは、変数名の前にlocalキーワードを付けることで、その変数をローカルスコープで宣言することができます。例えば、以下のようにして、xという変数を宣言することができます。
変数とデータ型

変数に初期値を代入する場合は、以下のように宣言と代入を同時に行うことができます。
変数とデータ型

Luaには、以下のようなデータ型があります。
変数とデータ型

変数に値を代入する場合は、以下のようにして行います。
変数とデータ型

また、代入された値を取り出して操作する場合は、以下のようにして行います。
変数とデータ型

文字列の場合は、以下のようにして連結することができます。
変数とデータ型

また、テーブルの場合は、以下のようにして要素を追加したり、削除したりすることができます。
変数とデータ型

これらの操作を利用して、Luaで様々な処理を行うことができます。
制御構文

以下は、Luaの制御構造のいくつかの例です。
制御構文

条件分岐にはif文を使用します。以下は、xが正の数であれば、"positive"と表示するプログラムの例です。
制御構文

また、if文の後にelseifを続けて書くことで、複数の条件分岐を行うことができます。
制御構文

Luaには、以下の3種類のループ処理があります。
制御構文

whileループは、条件式がtrueの間、繰り返し処理を行います。
制御構文

repeat-untilループは、条件式がtrueになるまで、繰り返し処理を行います。
制御構文

forループは、あらかじめ指定した回数分、繰り返し処理を行います。以下は、1から10までの数字を順番に表示するプログラムの例です。
制御構文

このコードは、Luaのforループを使用して1から10までの数値を2ずつ増やしながら順に取り出し、それぞれを出力するプログラムです。
制御構文

forループの書式は、以下のようになっています。
制御構文

初期値から始まり、終了値に達するまで、指定された増分ずつ値を増やしながらループ処理が実行されます。
制御構文

増分は省略可能で、その場合は 1 が仮定されます。
制御構文

今回のコードでは、初期値を1、終了値を10、増分を2としているため、1, 3, 5, 7, 9の5つの数値が順に取り出され、それぞれがprint()関数で出力されます。
制御構文

具体的に実行すると、以下のような結果が得られます。
制御構文

break文を使用することで、ループ処理を途中で終了することができます。
制御構文

以下は、1から10までの数字を順番に表示し、5になったらループを終了するプログラムの例です。
制御構文

関数を定義するには、以下のようにfunctionキーワードを使用します。また、引数を渡す場合は、()の中に引数名を書きます。
制御構文

関数を呼び出すには、関数名とともに引数を渡します。以下は、greet関数を呼び出すプログラムの例です。
制御構文

Luaにはキーワード引数がなく、関数の引数は位置引数として渡されます。
制御構文

可変長引数を受け取るため、Luaでは ... という構文があります。これは関数の引数リストの最後に置かれます。可変長引数は、呼び出し側が渡す引数の数によって異なります。関数内では、可変長引数はテーブルとして扱われます。たとえば、以下のようにして可変長引数を受け取る関数を定義できます。
制御構文

残余引数はありませんが、可変長引数を受け取った後に、任意の位置引数を受け取ることができます。たとえば、以下のようにして x という位置引数を受け取る関数を定義できます。
制御構文

Luaでは、関数もオブジェクトの一種であるため、変数に関数を代入することもできます。
制御構文

関数の返り値を取得するには、returnキーワードを使用します。
文字列操作

Luaは文字列操作に便利な機能を提供しています。文字列は、クォーテーションで囲んだ文字のシーケンスです。ダブルクォーテーションまたはシングルクォーテーションのどちらでも表現できます。
文字列操作

文字列は、..演算子で連結することができます。
文字列操作

文字列を部分的に取り出すには、string.sub関数を使用します。
文字列操作

また、文字列を逆順にするには、string.reverse関数を使用します。
文字列操作

Luaは、C言語と同様に、文字列のフォーマットに便利な機能を提供しています。string.format関数を使用して、文字列を特定の形式に整形することができます。
文字列操作

この例では、%sは文字列、%dは10進数、%.1fは小数点以下1桁の浮動小数点数を表します。string.format関数に渡す引数は、フォーマット文字列内の変数と一致する順序で指定する必要があります。
文字列操作

これらの機能を駆使することで、Luaで柔軟な文字列操作が可能になります。
テーブルと配列

Luaにおいて、テーブルは複数の値を格納するためのデータ構造の1つです。テーブルは配列や辞書のような形式で、キーと値をペアとして持ちます。
テーブルと配列

テーブルは、{}で作成することができます。以下のように、要素をカンマで区切って列挙することで初期化することができます。
テーブルと配列

また、以下のように、インデックスを指定して要素を追加することもできます。
テーブルと配列

テーブルに格納された要素には、以下のような方法でアクセスすることができます。
テーブルと配列

以下に、それぞれの操作の例を示します。
プロトタイプベースのオブジェクト指向

Luaはプロトタイプベースのオブジェクト指向言語であり、クラスを定義するのではなく、オブジェクトのプロトタイプを作成することでオブジェクトを生成します。
プロトタイプベースのオブジェクト指向

オブジェクトはテーブルとして表現され、オブジェクトの振る舞いや演算子の振る舞いを定義するために、テーブルにメソッドを追加できます。また、メソッドの呼び出しには「.」を使います。
プロトタイプベースのオブジェクト指向

メタテーブルは、テーブルに特定の動作を定義するために使用されます。例えば、メタテーブルを使用して、オブジェクトが加算、減算、比較などの演算をサポートするようにすることができます。
プロトタイプベースのオブジェクト指向

メタテーブルは、__index、__newindex、__add、__sub、__mul、__div、__mod、__pow、__unm、__eq、__lt、__le、__callなどの特殊なキーを持つテーブルとして定義されます。これらのキーには、特定の動作が関連付けられています。
プロトタイプベースのオブジェクト指向

具体的な例を見てみましょう。以下のようなAnimalテーブルを作成します。
プロトタイプベースのオブジェクト指向

この例では、Animalテーブルにsoundフィールドを定義し、new()関数をオブジェクト作成のために定義しています。makeSound()関数はAnimalオブジェクトが呼び出されたときに、オブジェクトのsoundフィールドの音を出力するために使用されます。
プロトタイプベースのオブジェクト指向

次に、AnimalテーブルからCatテーブルを作成します。
プロトタイプベースのオブジェクト指向

この例では、CatテーブルはAnimalテーブルから派生しており、CatオブジェクトにはmakeSound()メソッドが含まれ、soundフィールドには"Meow"という値が格納されています。scratch()メソッドも追加されました。
プロトタイプベースのオブジェクト指向

最後に、新しいCatオブジェクトを作成して、メソッドの動作を確認します。
プロトタイプベースのオブジェクト指向

この例では、Catテーブルを使用することで、AnimalテーブルのmakeSound()メソッドを再利用し、新しいメソッドscratch()を追加しました。また、メタテーブルを通じて、オブジェクトとしてのCatの振る舞いをカスタマイズすることもできます。
プロトタイプベースのオブジェクト指向

ユーザー定義のオブジェクトの例として、複素数オブジェクトの定義を取り上げます。
LuaRocks

LuaRocksは、Lua言語用のパッケージ管理ツールです。 このツールを使用すると、Luaの拡張機能やユーティリティを簡単にインストール、アップグレード、削除することができます。 LuaRocksを使うためには、先にLuaのランタイムが必要になります。
LuaRocks

以下に、LuaRocksの基本的な使い方を説明します。
LuaRocks

新しいパッケージをインストールするには、以下のコマンドを実行します。
LuaRocks

たとえば、luasocketというパッケージをインストールする場合は、以下のように入力します。
LuaRocks

不要なパッケージをアンインストールするには、以下のコマンドを実行します。
LuaRocks

たとえば、先ほどインストールしたluasocketパッケージをアンインストールする場合は、以下のように入力します。
LuaRocks

インストールされているパッケージの一覧を表示するには、以下のコマンドを入力します。
LuaRocks

インストールされているパッケージのバージョンを確認するには、以下のコマンドを入力します。
LuaRocks

ただし、このコマンドはインストールされているパッケージに限定されます。インストールされていないパッケージのバージョンを確認したい場合は、以下のように入力します。
LuaRocks

以上が、LuaRocksの基本的な使い方です。これらのコマンドを実行することで、Luaの拡張機能やユーティリティを簡単にインストール、アップグレード、削除することができます。
Luadoc

LuaDocは、Luaのドキュメンテーションツールであり、ソースコード内にある関数やモジュールについての情報を自動的に抽出して、HTML、XML、またはテキスト形式のドキュメントを生成することができます。
Luadoc

以下に、LuaDocによって生成されたドキュメントに含まれる情報の種類を示します。
Luadoc

LuaDocは、Luaのテーブル、オブジェクト指向プログラミング、およびバージョン制御システムにも対応しています。また、LuaDocは、ユーザー定義のタグを使用して、カスタムタグを作成することもできます。
Luadoc

LuaDocには、以下のような主な機能があります。
Luadoc

ユーザー定義の拡張 LuaDocは、ユーザーが独自のタグを定義して、ドキュメント化する情報をカスタマイズすることができます。
Luadoc

以上が、LuaDocの概要です。LuaDocは、Luaコミュニティーにおいて、広く使われているドキュメンテーションツールであり、Luaプロジェクトの開発者にとって重要なツールの1つです。
Luadoc

LuaDocで使用される基本構文の例です。
Luadoc

Luadocは、特殊な方法でLuaのコメントを認識します。次のような例です。
Luadoc

---で始まる行は、LuaDocによってドキュメントの一部として解釈されます。コメント行を続けて行うことが可能で、それらは全て同じドキュメントテキストとして処理されます。
Luadoc

コメントには、行に続くタグも含められることがあります。コメントとタグの間には、スペースが必要です。
Luadoc

LuaDocでは、いくつかのドキュメントタグが使用されます。下記に例を挙げます。
Luadoc

関数の引数の説明を提供します。
Luadoc

関数が返す値を説明します。
Luadoc

関数などの関連する内容を参照先を説明するタグ。
Luadoc

このようにして、LuaDocを使用することで、Luaのコードに対してドキュメントを自動的に生成することができます。
Luadoc

Luadocは、コメントに記述された特定のパターンを解析し、ドキュメントの生成に使用します。コメントに挿入されるタグの例をいくつか示します。
Luadoc

リファレンスの生成、文書のビルド、ソースコードのプロファイリングなど、Luadocのさまざまなコマンドを利用できます。以下はいくつかの代表的なコマンドです。
ファイル入出力

以下はLuaにおけるファイル入出力に関する基本的な操作の例です。
ファイル入出力

上記の例では、io.open関数を使ってファイルを開き、file変数に代入しています。第一引数にファイル名、第二引数にモードを指定します。rモードは読み込み専用モードを表します。
ファイル入出力

次に、file:lines()を使ってファイルから1行ずつ読み込み、forループを使って行を出力しています。
ファイル入出力

最後に、ファイルを閉じるためにfile:close()を呼び出しています。
ファイル入出力

上記の例では、io.open関数を使ってファイルを開き、file変数に代入しています。第一引数にファイル名、第二引数にモードを指定します。wモードは書き込み専用モードを表します。既存のファイルがある場合、内容が上書きされます。
ファイル入出力

次に、file:write()を使ってファイルに文字列を書き込んでいます。
ファイル入出力

最後に、ファイルを閉じるためにfile:close()を呼び出しています。
ファイル入出力

上記の例では、ファイルへの書き込みが完了した時点で、ファイルが閉じられるため、ファイルを明示的に閉じる必要はありません。ただし、ファイルを開いたままにしておくと、メモリリークなどの問題が発生する可能性があるため、ファイルの操作が終了したら必ずfile:close()を呼び出すようにしてください。
モジュールとパッケージ

モジュールとは、一連の関数や変数をまとめたもので、再利用性を高めたコードの共有方法です。パッケージは、複数のモジュールをまとめて管理する方法です。
モジュールとパッケージ

Luaにおいて、モジュールはテーブルを使って実装されます。通常、モジュールは新しいテーブルを作成して、そこに関数や変数を格納します。モジュールを利用する側は、そのモジュールが提供する関数や変数にアクセスするために、モジュールをロードする必要があります。
モジュールとパッケージ

パッケージは、複数のモジュールを一つのパッケージにまとめ、そのパッケージを利用する方法を提供します。パッケージには、一つ以上のモジュールが含まれている場合があります。通常、パッケージはディレクトリ階層を使って管理され、パッケージの名前はディレクトリ名に対応します。パッケージは、Luaの標準ライブラリからロードすることもできますし、カスタムのパッケージを作成することもできます。
モジュールとパッケージ

以下は、モジュールとパッケージの例です。
モジュールとパッケージ

これらのコードは、"mymodule.lua"という名前のモジュールを作成し、"main.lua"でロードして使用する例と、"mypackage"という名前のパッケージを作成し、その中に"mymodule"という名前のモジュールを含めて、"main.lua"で使用する例を示しています。
Luaの拡張性とC API

Luaは、C言語による拡張が容易に行えるように設計されています。LuaのC APIを使うことで、C言語で書かれたモジュールやライブラリをLuaから利用することができます。 LuaのC APIは、Luaの仕様に基づいて作られているため、C言語からLuaスクリプトを実行したり、LuaスクリプトからC言語の関数を呼び出したりすることができます。
Luaの拡張性とC API

Luaは拡張性に優れたスクリプト言語で、ホストアプリケーションに合わせて柔軟にカスタマイズすることができます。LuaはCで実装されており、C APIを通じてLuaの機能を拡張することができます。
Luaの拡張性とC API

C APIを使用することで、CプログラムからLuaスクリプトを呼び出すことができます。また、LuaスクリプトからC関数を呼び出すこともできます。C APIには、Luaの値のスタックを操作するための関数や、新しい関数やテーブルを作成するための関数などが含まれています。
Luaの拡張性とC API

例えば、以下のようなCプログラムを考えてみましょう。
Luaの拡張性とC API

このプログラムでは、luaL_newstate関数でLuaステートを作成し、luaL_openlibs関数でLuaの標準ライブラリをオープンしています。そして、luaL_dostring関数でLuaスクリプトを実行しています。最後に、lua_close関数でLuaステートを解放しています。
Luaの拡張性とC API

このように、C APIを使用することでLuaの機能を拡張することができます。しかし、C APIは複雑であるため、Luaの基礎を理解した上で使用することをおすすめします。
プロジェクト例

以下は、数を受け取り、それが偶数か奇数かを判定する簡単なLuaプログラムの例です。
プロジェクト例

このプログラムでは、 even_or_odd 関数が数値が偶数か奇数かを判定するために使用されています。その後、 io ライブラリを使用してユーザーから数値を取得し、 even_or_odd 関数を呼び出して結果を表示します。
プロジェクト例

次に、このプログラムを改良して、偶数と奇数のカウントを追加してみましょう。
プロジェクト例

このプログラムでは、偶数と奇数のカウントが even_count と odd_count 変数に格納されます。その後、ループの最後にそれらを表示します。
プロジェクト例

このプログラムは、より複雑な機能を追加して、Luaプログラムを改良し、拡張する方法を示しています。
附録

このLuaのコードは、エラトステネスの篩を使って与えられた n までの素数を見つける関数 eratosthenes を定義しています。
附録

このプログラムは eratosthenes(100) を呼び出すことで、100 までの素数を見つけて表示します。
附録

このLuaのコードは、最大公約数(GCD)と最小公倍数(LCM)を計算する関数を提供しています。まず、gcd2関数は、最大公約数を再帰的に求めるためのものです。与えられた2つの数値の最大公約数を計算します。gcd関数は可変長引数を受け取り、それらの数値の最大公約数を計算します。lcm2関数は2つの数値の最小公倍数を計算し、lcm関数は可変長引数を持ち、それらの数値の最小公倍数を計算します。
附録

最後に、それぞれの関数を用いてgcd2、gcd、lcm2、lcmを実行し、結果を出力しています。これらの関数を使って、与えられた数値の最大公約数と最小公倍数を求めることができます。
附録

二分法
附録

このLuaのコードは、二分法を使って関数の根(方程式の解)を見つけるための関数 bisection を実装しています。ここで、渡された関数 f は、与えられた範囲 low と high の間で解を探索します。絶対値が非常に小さい(この場合は 1.0e-10 より小さい)値を見つけた場合、その x の値を解として返します。
附録

次に、与えられた2つの方程式に対して bisection 関数を使用し、それぞれの解を求めています。
附録

それぞれの解が print を使ってコンソールに出力されます。このように、bisection 関数を用いて与えられた関数の根を見つけることができます。