この初版は Lua 5.0 向けに書かれました。後期のバージョンでもまだほとんど関連がありますが、いくつかの違いがあります。
第 4 版は Lua 5.3 をターゲットにしており、Amazon や他の書店で入手できます。
本を購入することで、Lua プロジェクトをサポートすることにもつながります。
![]() |
でプログラミングLua | ![]() |
第 II 部 テーブルとオブジェクト 第 14 章 環境 |
通常は、代入でグローバル変数の取得と設定ができます。しかし、メタプログラミングの一種が必要になることがよくあります。たとえば、別の変数に格納されている名前のグローバル変数を操作したり、何らかの方法で実行時に計算したりする必要がある場合などです。この変数の値を取得するために、多くのプログラマーは次のようなコードを書くことに誘惑されます。
loadstring("value = " .. varname)()または
value = loadstring("return " .. varname)()たとえば、
varname
が x
の場合、連結の結果は "return x"
(または最初の形式の場合は "value = x"
)になります。実行すると、目的の結果が得られます。しかし、そのようなコードには新しいチャンクの作成とコンパイル、および多数の追加作業が含まれます。同じ効果は、次のようなコードで実現できます。これは、前のコードよりも桁違いに効率的です。value = _G[varname]環境は通常のテーブルなので、目的のキー(変数名)でインデックスを付けるだけで済みます。
同様に、_G[varname] = value
と記述することで、動的に計算された名前のグローバル変数に代入できます。ただし、注意が必要です。これらの関数に少し興奮したプログラマーの中には、_G["a"] = _G["var1"]
のようなコードを書く人もいますが、これは a = var1
と記述する複雑な方法にすぎません。
前述の問題の一般化は、"io.read"
や "a.b.c.d"
などの動的名前のフィールドを許可することです。この問題は、_G
から開始され、フィールドごとに進化するループで解決します。
function getfield (f) local v = _G -- start with the table of globals for w in string.gfind(f, "[%w_]+") do v = v[w] end return v end
f
のすべての単語(「単語」は英数字と下線文字のシーケンスの 1 つ以上)を反復処理するために、string
ライブラリからの gfind
に依存します。フィールドを設定するための対応する関数は、少し複雑です。次のような代入は
a.b.c.d.e = v次の場合とまったく同じです。
local temp = a.b.c.d temp.e = vつまり、最後の名前まで取得する必要があります。最後のフィールドは別途処理しなければなりません。新しい
setfield
関数は、存在しない場合にパスの途中に中間テーブルも作成します。function setfield (f, v) local t = _G -- start with the table of globals for w, d in string.gfind(f, "([%w_]+)(.?)") do if d == "." then -- not last field? t[w] = t[w] or {} -- create table if absent t = t[w] -- get the table else -- last field t[w] = v -- do the assignment end end endこの新しいパターンは、変数
w
にフィールド名と、続くオプションのドットを d
にキャプチャします。フィールド名の後にドットが続かない場合は、それは最後の名前です(パターンマッチングについては、第 20 章 で詳しく説明します)。前の関数を使用すると、コールがあります。
setfield("t.x.y", 10)グローバルテーブル
t
、別のテーブル t.x
を作成し、10 を t.x.y
に代入します。print(t.x.y) --> 10 print(getfield("t.x.y")) --> 10
© 2003–2004 Roberto Ierusalimschy。すべての権利を保有しています。 | ![]() |