この初版は Lua 5.0 向けに書かれました。後のバージョンでもほとんどは関連っていますが、多少の相違があります。
第 4 版は Lua 5.3 を対象としており、Amazon や他の書店で購入できます。
この本を購入することにより、Lua プロジェクトへの支援にも貢献できます。
![]() |
Programming inLua | ![]() |
第 2 部。テーブルとオブジェクト 第 12 章。データファイルと永続性 |
一般的なトポロジー(つまり、サイクルや共有サブテーブルを含む)のテーブルを扱うには、別の方法が必要です。コンストラクタはこれらのテーブルを表すことができないため、ここでは使用しません。サイクルを表すには名前が必要なので、次の関数は保存される値とその名前を引数として受け取ります。さらに、サイクルが検出されたときに再利用できるように、すでに保存されたテーブルの名前を追跡しておく必要があります。この追跡にはもう 1 つのテーブルを使用します。このテーブルはテーブルをインデックスとして、対応する値として名前を持ちます。
保存するテーブルのキーは文字列または数値のみという制約を維持します。次の関数はこれらの基本タイプをシリアル化し、結果を返します
function basicSerialize (o) if type(o) == "number" then return tostring(o) else -- assume it is a string return string.format("%q", o) end end次の関数が大変な作業を行います。
saved
パラメータはすでに保存されたテーブルを追跡するテーブルですfunction save (name, value, saved) saved = saved or {} -- initial value io.write(name, " = ") if type(value) == "number" or type(value) == "string" then io.write(basicSerialize(value), "\n") elseif type(value) == "table" then if saved[value] then -- value already saved? io.write(saved[value], "\n") -- use its previous name else saved[value] = name -- save name for next time io.write("{}\n") -- create a new table for k,v in pairs(value) do -- save its fields local fieldname = string.format("%s[%s]", name, basicSerialize(k)) save(fieldname, v, saved) end end else error("cannot save a " .. type(value)) end endたとえば、次のようないテーブルを構築する場合
a = {x=1, y=2; {3,4,5}} a[2] = a -- cycle a.z = a[1] -- shared sub-table
save('a', a)
の呼び出しは次のように保存します。a = {} a[1] = {} a[1][1] = 3 a[1][2] = 4 a[1][3] = 5 a[2] = a a["y"] = 2 a["x"] = 1 a["z"] = a[1](これらの代入の実際の順序は、テーブルの走査に依存するため異なる場合があります。それでも、このアルゴリズムにより、新しい定義に必要な以前のノードはすでに定義されていることが保証されます。)
共有部分を伴う複数の値を保存する場合は、同じ saved
テーブルを使用して save
を呼び出すことができます。たとえば、次の 2 つのテーブルを作成する場合
a = {{"one", "two"}, 3} b = {k = a[1]}次のように保存すると
save('a', a) save('b', b)結果は共通部分を持ちません
a = {} a[1] = {} a[1][1] = "one" a[1][2] = "two" a[2] = 3 b = {} b["k"] = {} b["k"][1] = "one" b["k"][2] = "two"しかし、
save
の各呼び出しに同じ saved
テーブルを使用するとlocal t = {} save('a', a, t) save('b', b, t)結果は共通部分を共有します
a = {} a[1] = {} a[1][1] = "one" a[1][2] = "two" a[2] = 3 b = {} b["k"] = a[1]
Lua ではいつものことですが、他にもいくつかの選択肢があります。その中には、値にグローバル名を与えずに保存するもの(代わりに、チャンクでローカル値を作成してそれを返します)、関数(それぞれの関数をその名前に関連付けるテーブルを作成します)を扱うものなどがあります。Lua はその機能を提供します。仕組みは自分で構築します。
著作権 © 2003–2004 Roberto Ierusalimschy。全著作権所有。 | ![]() |