Lua-metatables
Lua-メタテーブル
メタテーブルは、キーセットおよび関連するメタメソッドの助けを借りて、アタッチされているテーブルの動作を変更するのに役立つテーブルです。 これらのメタメソッドは、次のような機能を有効にする強力なLua機能です-
- テーブルの演算子への機能の変更/追加。
- メタテーブルで__indexを使用して、キーがテーブルで使用できないときにメタテーブルを検索します。
以下を含むメタテーブルの処理に使用される2つの重要な方法があります-
- * setmetatable(table、metatable)*-このメソッドは、テーブルのメタテーブルを設定するために使用されます。
- * getmetatable(table)*-このメソッドは、テーブルのメタテーブルを取得するために使用されます。
最初に、あるテーブルを別のテーブルのメタテーブルとして設定する方法を見てみましょう。 以下に示します。
mytable = {}
mymetatable = {}
setmetatable(mytable,mymetatable)
上記のコードは、次のように1行で表すことができます。
mytable = setmetatable({},{})
_index
メタテーブルがテーブルで利用できない場合にメタテーブルを検索するためのメタテーブルの簡単な例を以下に示します。
mytable = setmetatable({key1 = "value1"}, {
__index = function(mytable, key)
if key == "key2" then
return "metatablevalue"
else
return mytable[key]
end
end
})
print(mytable.key1,mytable.key2)
上記のプログラムを実行すると、次の出力が得られます。
value1 metatablevalue
上記の例で何が起こったのかを段階的に説明しましょう。
- ここのテーブルmytableは \ {key1 = "value1"} です。
- メタテーブルは、メタメソッドとして呼び出す__indexの関数を含むmytableに設定されます。 *メタメソッドは、インデックス "key2"を検索するという単純な作業を行い、見つかった場合は "metatablevalue"を返し、そうでない場合は対応するインデックスのmytableの値を返します。
以下に示すように、上記のプログラムの簡易バージョンを作成できます。
mytable = setmetatable({key1 = "value1"},
{ __index = { key2 = "metatablevalue" } })
print(mytable.key1,mytable.key2)
__newindex
__newindexをメタテーブルに追加するときに、テーブルでキーが使用できない場合、新しいキーの動作はメタメソッドによって定義されます。 メインテーブルでインデックスが使用できない場合にメタテーブルのインデックスが設定される簡単な例を以下に示します。
mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })
print(mytable.key1)
mytable.newkey = "new value 2"
print(mytable.newkey,mymetatable.newkey)
mytable.key1 = "new value 1"
print(mytable.key1,mymetatable.newkey1)
上記のプログラムを実行すると、次の出力が得られます。
value1
nil new value 2
new value 1 nil
上記のプログラムを見るとわかるように、メインテーブルにキーが存在する場合は更新されます。 キーがメインテーブルで使用できない場合、そのキーをメタテーブルに追加します。
rawset関数を使用して同じテーブルを更新する別の例を以下に示します。
mytable = setmetatable({key1 = "value1"}, {
__newindex = function(mytable, key, value)
rawset(mytable, key, "\""..value.."\"")
end
})
mytable.key1 = "new value"
mytable.key2 = 4
print(mytable.key1,mytable.key2)
上記のプログラムを実行すると、次の出力が得られます。
new value "4"
rawsetは、メタテーブルのnewindexを使用せずに値を設定します。 同様に、 indexを使用せずに値を取得するrawgetがあります。
テーブルへのオペレーターの動作の追加
+を使用して2つのテーブルを結合する簡単な例演算子は以下に示されています-
mytable = setmetatable({ 1, 2, 3 }, {
__add = function(mytable, newtable)
for i = 1, table.maxn(newtable) do
table.insert(mytable, table.maxn(mytable)+1,newtable[i])
end
return mytable
end
})
secondtable = {4,5,6}
mytable = mytable + secondtable
for k,v in ipairs(mytable) do
print(k,v)
end
上記のプログラムを実行すると、次の出力が得られます。
1 1
2 2
3 3
4 4
5 5
6 6
演算子+の動作を追加するために、__ addキーがメタテーブルに含まれています。 キーと対応する演算子の表を以下に示します。
Sr.No. | Mode & Description |
---|---|
1 |
演算子「+」の動作を変更します。 |
2 |
__sub 演算子「-」の動作を変更します。 |
3 |
__mul 演算子「*」の動作を変更します。 |
4 |
__div 演算子「/」の動作を変更します。 |
5 |
__mod 演算子 '%'の動作を変更します。 |
6 |
__unm 演算子「-」の動作を変更します。 |
7 |
__concat 演算子「..」の動作を変更します。 |
8 |
__eq 演算子「==」の動作を変更します。 |
9 |
__lt 演算子「<」の動作を変更します。 |
10 |
__le 演算子「⇐」の動作を変更します。 |
__コール
メソッド呼び出しの動作を追加するには、__ callステートメントを使用します。 メインテーブルの値の合計と、渡されたテーブルを返す簡単な例。
mytable = setmetatable({10}, {
__call = function(mytable, newtable)
sum = 0
for i = 1, table.maxn(mytable) do
sum = sum + mytable[i]
end
for i = 1, table.maxn(newtable) do
sum = sum + newtable[i]
end
return sum
end
})
newtable = {10,20,30}
print(mytable(newtable))
上記のプログラムを実行すると、次の出力が得られます。
70
__tostring
printステートメントの動作を変更するには、__ tostringメタメソッドを使用できます。 以下に簡単な例を示します。
mytable = setmetatable({ 10, 20, 30 }, {
__tostring = function(mytable)
sum = 0
for k, v in pairs(mytable) do
sum = sum + v
end
return "The sum of values in the table is " .. sum
end
})
print(mytable)
上記のプログラムを実行すると、次の出力が得られます。
The sum of values in the table is 60
メタテーブルの機能を完全に理解している場合は、使用しなくても非常に複雑な多くの操作を実際に実行できます。 そのため、サンプルで説明されているように、メタテーブルで使用可能なさまざまなオプションを使用してメタテーブルを使用し、独自のサンプルを作成してください。