この初版はLua 5.0向けに書かれています。後続のバージョンでも大部分は関連性がありますが、いくつかの違いがあります。
第4版はLua 5.3を対象としており、Amazonおよびその他の書店で購入できます。
本書を購入することで、Luaプロジェクトの支援にもつながります。


8.1 – require 関数

Luaは、ライブラリをロードして実行するためのより高レベルな関数requireを提供します。おおよそ、requiredofileと同じ機能を果たしますが、2つの重要な違いがあります。まず、requireはパスでファイルを検索します。第二に、requireはファイルが既に実行済みかどうかを制御して、作業の重複を回避します。これらの機能により、requireはLuaでライブラリをロードするための推奨関数となっています。

requireで使用されるパスは、一般的なパスとは少し異なります。ほとんどのプログラムは、特定のファイルを検索するディレクトリのリストとしてパスを使用します。しかし、ANSI C(Luaが動作する抽象的なプラットフォーム)には、ディレクトリの概念がありません。したがって、requireで使用されるパスは、 *パターン* のリストであり、それぞれが仮想ファイル名(requireへの引数)を実際のファイル名に変換する代替方法を指定します。より具体的には、パス内の各コンポーネントは、オプションの疑問符を含むファイル名です。各コンポーネントについて、requireは各`?´を仮想ファイル名に置き換え、その名前のファイルが存在するかどうかをチェックします。存在しない場合は、次のコンポーネントに進みます。パスのコンポーネントはセミコロン(ほとんどのオペレーティングシステムではファイル名にほとんど使用されない文字)で区切られています。たとえば、パスが

    ?;?.lua;c:\windows\?;/usr/local/lua/?/?.lua
であれば、require"lili"の呼び出しは、次のファイルを開こうとします。
    lili
    lili.lua
    c:\windows\lili
    /usr/local/lua/lili/lili.lua
requireが修正するのは、セミコロン(コンポーネントの区切り文字)と疑問符だけです。その他すべて(ディレクトリ区切り文字やファイル拡張子など)はパスで定義されます。

パスを決定するために、requireは最初にグローバル変数LUA_PATHをチェックします。LUA_PATHの値が文字列の場合、その文字列がパスとなります。それ以外の場合は、環境変数LUA_PATHをチェックします。最後に、両方のチェックが失敗した場合、requireは固定パス(通常は"?;?.lua"ですが、Luaをコンパイルするときに簡単に変更できます)を使用します。

requireのもう1つの主な役割は、同じファイルを2回ロードすることを避けることです。その目的のために、ロードされたすべてのファイルの名前を含むテーブルを保持します。必要なファイルが既にテーブルにある場合、requireは単に返ります。テーブルは、ロードされたファイルの実際の名前ではなく、仮想名を保持します。したがって、同じファイルを2つの異なる仮想名でロードした場合、2回ロードされます。たとえば、パスが"?;?.lua"の場合、require"foo"の後にrequire"foo.lua"を実行すると、foo.luaファイルが2回ロードされます。この制御テーブルには、グローバル変数_LOADEDを通じてアクセスできます。このテーブルを使用して、どのファイルがロードされたかを確認できます。また、requireをだましてファイルを2回実行することもできます。たとえば、require"foo"が成功した後、_LOADED["foo"]nilではありません。その後、_LOADED["foo"]nilを代入すると、後続のrequire"foo"はファイルを再度実行します。

コンポーネントには疑問符が含まれている必要はありません。次のパスの最後のコンポーネントなど、固定ファイル名にすることができます。

    ?;?.lua;/usr/local/default.lua
この場合、requireが他のオプションを見つけられないときはいつでも、この固定ファイルを実行します。(もちろん、固定コンポーネントをパスの最後のコンポーネントとして持つのは理にかなっています。)requireがチャンクを実行する前に、要求されているファイルの仮想名を含むグローバル変数_REQUIREDNAMEを定義します。これらの機能を使用して、requireの機能を拡張できます。極端な例として、パスを"/usr/local/lua/newrequire.lua"のようなものにすることができます。これにより、requireへのすべての呼び出しでnewrequire.luaが実行され、そこで_REQUIREDNAMEの値を使用して、実際に必要なファイルをロードできます。