この初版は、Lua 5.0 用に書かれました。後のバージョンでもほぼ関連性がありますが、いくつかの違いがあります。
第 4 版は Lua 5.3 を対象としており、Amazon と他の書店で入手できます。
この本を購入することで、Lua プロジェクトを支援することにも貢献できます。


10.1 – データ記述

Lua サイトには、世界中の Lua を使用するプロジェクトのサンプルを含むデータベースが置かれています。以下の例に示すように、各エントリをデータベースで、オートドキュメント化された方法でコンストラクタで表します。

    entry{
      title = "Tecgraf",
      org = "Computer Graphics Technology Group, PUC-Rio",
      url = "http://www.tecgraf.puc-rio.br/",
      contact = "Waldemar Celes",
      description = [[
        TeCGraf is the result of a partnership between PUC-Rio,
        the Pontifical Catholic University of Rio de Janeiro,
        and <A HREF="http://www.petrobras.com.br/">PETROBRAS</A>,
        the Brazilian Oil Company.
        TeCGraf is Lua's birthplace,
        and the language has been used there since 1993.
        Currently, more than thirty programmers in TeCGraf use
        Lua regularly; they have written more than two hundred
        thousand lines of code, distributed among dozens of
        final products.]]
      }
この表現の興味深い点は、このようなエントリのシーケンスを持つファイルは Lua プログラムであり、テーブルを呼び出し引数として使用して、関数 entry に対する一連の呼び出しを実行するということです。

私たちの目標は、そのデータを HTML で表示し、https://lua.dokyumento.jp/uses.html という Web ページになるプログラムを書くことです。プロジェクトが多数あるため、最終ページには最初にすべてのプロジェクト タイトルのリストが表示され、次に各プロジェクトの詳細が表示されます。プログラムの結果は次のようになります。

    <HTML>
    <HEAD><TITLE>Projects using Lua</TITLE></HEAD>
    <BODY BGCOLOR="#FFFFFF">
    Here are brief descriptions of some projects around the
    world that use <A HREF="home.html">Lua</A>.
    <BR>
    <UL>
    <LI><A HREF="#1">TeCGraf</A>
    <LI> ...
    </UL>
    
    <H3>
    <A NAME="1" HREF="http://www.tecgraf.puc-rio.br/">TeCGraf</A>
    <BR>
    <SMALL><EM>Computer Graphics Technology Group,
               PUC-Rio</EM></SMALL>
    </H3>
    
        TeCGraf is the result of a partnership between
        ...
        distributed among dozens of final products.<P>
    Contact: Waldemar Celes
    
    <A NAME="2"></A><HR>
    ...
    
    </BODY></HTML>

このデータをロードするには、entry に適切な定義を与えて、データファイルをプログラム(dofile を使用)として実行するだけです。すべてのエントリを 2 回トラバースする必要があることに注意してください。最初はタイトル リストのため、次にプロジェクトの説明のためです。最初の方法は、すべてのエントリを配列に格納することです。ただし、Lua はコンパイルするのが非常に高速であるため、別の魅力的な解決策があります。データファイルを 2 回実行し、それぞれで entry に異なる定義を使用します。この方法を次のプログラムで採用します。

最初に、フォーマットされたテキストを書くための補助関数を定義します(この関数は既に 5.2 節 で見ました)。

    function fwrite (fmt, ...)
      return io.write(string.format(fmt, unpack(arg)))
    end

BEGIN 関数は単にページ ヘッダーを書き込みます。ヘッダーは常に同じです。

    function BEGIN()
      io.write([[
        <HTML>
        <HEAD><TITLE>Projects using Lua</TITLE></HEAD>
        <BODY BGCOLOR="#FFFFFF">
        Here are brief descriptions of some projects around the
        world that use <A HREF="home.html">Lua</A>.
        <BR>
      ]])
    end

entry の最初の定義では、各タイトルのプロジェクトをリスト項目として書き込みます。引数 o はプロジェクトを記述するテーブルです。

    function entry0 (o)
      N=N + 1
      local title = o.title or '(no title)'
      fwrite('<LI><A HREF="#%d">%s</A>\n', N, title)
    end
o.titlenil の場合(つまり、フィールドが提供されなかった場合)、関数は固定文字列 "(no title)" を使用します。

2 番目の定義は、プロジェクトに関するすべての有用なデータを書き込みます。これは、すべての項目がオプションであるため、もう少し複雑です。

    function entry1 (o)
      N=N + 1
      local title = o.title or o.org or 'org'
      fwrite('<HR>\n<H3>\n')
      local href = ''
    
      if o.url then
        href = string.format(' HREF="%s"', o.url)
      end
      fwrite('<A NAME="%d"%s>%s</A>\n', N, href, title)
    
      if o.title and o.org then
        fwrite('<BR>\n<SMALL><EM>%s</EM></SMALL>', o.org)
      end
      fwrite('\n</H3>\n')
    
      if o.description then
        fwrite('%s', string.gsub(o.description,
                                 '\n\n\n*', '<P>\n'))
        fwrite('<P>\n')
      end
    
      if o.email then
        fwrite('Contact: <A HREF="mailto:%s">%s</A>\n',
               o.email, o.contact or o.email)
      elseif o.contact then
        fwrite('Contact: %s\n', o.contact)
      end
    end
(二重引用符を使用している HTML との競合を避けるため、このプログラムでは単一引用符のみを使用しました。)最後の関数はページを閉じます。
    function END()
      fwrite('</BODY></HTML>\n')
    end
最後に、メイン プログラムはページを起動し、entryentry0)の最初の定義を使用してデータ ファイルを実行してタイトル リストを作成してから、entry の 2 番目の定義を使用してデータ ファイルを再度実行し、ページを閉じます。
    BEGIN()
    
    N = 0
    entry = entry0
    fwrite('<UL>\n')
    dofile('db.lua')
    fwrite('</UL>\n')
    
    N = 0
    entry = entry1
    dofile('db.lua')
    
    END()