この初版は 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。全著作権所有。 | ![]() |