Luaでrefのようなものを作る
Luaでrefのようなものを作る
Luaで参照のようなものを作ります。テーブルに対する「参照値」ではなくプリミティブにも使える参照のような動作をするものです。
実装の方針
メタメソッドの __index
および __newIndex
によってテーブルへのアクセスを制御することができることを利用します。参照名と参照先 (テーブルとキーのペア) の対応を保持しローバルのrefオブジェクトへのアクセスにより参照先を操作します。
実装
refオブジェクト
refオブジェクトに次のメンバを持たせます。
キー | 型 | 値 |
---|---|---|
table | "table" | 参照名と参照先のリスト |
put | "function" | 参照を追加するメソッド |
delete | "function" | 参照を削除するメソッド |
今回は簡単のためrefはグローバルオブジェクトとしますがインスタンスとする場合はメタテーブルから put
メソッドと delete
メソッドを呼べるようにすればよいです。
インデックスへのアクセス
refオブジェクトの __index
を設定します。フィールドにアクセスされるとこの関数が呼ばれるため、 ref.table
内を参照して返します。ただし put
メソッドや delete
メソッドへのアクセスは特別に直接 ref
オブジェクト内のメソッドを呼び出します。呼び出しが循環しないために rawget
メソッドを使い ref
内のフィールドを直接参照します。なお、コード内ではメタテーブルに設定するためのオブジェクトを meta
と表しています。
meta.__index = function(ref, key)
if type(ref) ~= "table" then
return nil
end
-- putフィールドとdeleteフィールドはref内を直接参照
if key == "put" or key == "delete" then
return rawget(ref, key);
end
-- ref.table内のフィールドを参照
local obj = rawget(ref, "table")[key]
if obj ~= nil then
return (obj.table)[obj.key]
end
return nil
end
代入も同様にして行えます。
meta.__newindex = function(ref, key, value)
if type(ref) ~= "table" then
return nil
end
-- ref.table内のフィールドを参照
local obj = rawget(ref, "table")[key]
if obj ~= nil then
(obj.table)[obj.key] = value
end
end
put
メソッドと delete
メソッドは単純に ref.table
内を書き換えるだけです。メタテーブルの設定前に書くと rawget
を使わずに済みます。
ref.put = function(name, table, key)
rawget(ref, "table")[name] = {
table = table,
key = key
}
end
ref.delete = function(name)
rawget(ref, "table")[name] = nil
end
振る舞い
次のように参照のような使い方をできます。ただしテーブルへの参照はテーブルを参照する値への参照になります。
local table = {
a = 0
}
ref.put("a", table, "a")
ref.put("a2", table, "a")
print(table.a .. ", " .. ref.a .. ", " .. ref.a2) -- 0, 0, 0
table.a = 10
print(table.a .. ", " .. ref.a .. ", " .. ref.a2) -- 10, 10, 10
ref.a = 20
print(table.a .. ", " .. ref.a .. ", " .. ref.a2) -- 20, 20, 20
ref.a2 = 30
print(table.a .. ", " .. ref.a .. ", " .. ref.a2) -- 30, 30, 30
また、次のように参照に対して参照を設定することもできます。この場合も結果は同様です。
ref.put("a2", ref, "a")
Author And Source
この問題について(Luaでrefのようなものを作る), 我々は、より多くの情報をここで見つけました https://qiita.com/Tsukina_7mochi/items/f3c051c74fe85bbbe9ce著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .