Luaのメタテーブルの概念を説明する
メタテーブルは、接続するキーセットと、その下にあるヘルパーテーブルの関連メタメソッドの動作を変更するのに役立つテーブルです。これらのメタ・メソッドは、以下のような強力なluaの機能です。
- 演算子テーブルの変更・関数追加
- インデックス・メタ・テーブルを使用して、テーブルにキーがない場合にメタ・テーブルを表示する。
メタテーブルの処理には、次の2つの重要な方法があることが示されています。
- setmetatable(table,metatable)。このメソッドは、メタデータにテーブルを設定するために使用されます。
- getmetatable(table): このメソッドは、テーブルのメタデータを取得するために使用されます。
まず、テーブルを別のメタデータとして設定する方法から見ていきましょう。それは以下のようになります。
mymetatable = {}
setmetatable(mytable,mymetatable)
上記のコードを1行で表すと、次のようになります。
__index
テーブルのルックアップ・メタ・テーブルで提供されない場合の簡単な例を以下に示します。
__index = function(mytable, key)
if key == "key2" then
return "metatablevalue"
else
return mytable[key]
end
end
})
print(mytable.key1,mytable.key2)
上記のプログラムを実行すると、次のような出力が得られます。
上の例の手順で、何が起こったかを説明しましょう。
- ここでテーブルmytableは{key1 = "value1"}です。
- メタテーブルには、メタメソッドと呼んでいるmytable内の関数__indexが設定されています。
- meta メソッドは、インデックス "key2" を調べて、見つかれば "metatablevalue" を返し、そうでなければ対応する mytable インデックスの値を返すという簡単な仕事をします。
上記のプログラムを簡略化すると、次のようになる。
print(mytable.key1,mytable.key2)
__newindex
メタテーブルに __newindex を追加したとき、そのキーがテーブル内にない場合は、新しいキーの動作はリレーメソッドで定義されます。主テーブルにインデックスがない場合のメタテーブルのインデックスを設定する簡単な例は、次のようになります。
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)
上記のプログラムを実行すると、次のような出力が得られます。
nil new value 2
new value 1 nil
上のプログラムを見ればわかるように、メインテーブルにキーが存在する場合は、それを更新するだけです。メインテーブルにキーがない場合は、キーメタレートを追加しています。
また、同じテーブルに対してrawset関数を用いて更新した例を以下に示します。
__newindex = function(mytable, key, value)
rawset(mytable, key, "\"". .value. "\"")
end
})
mytable.key1 = "new value"
mytable.key2 = 4
print(mytable.key1,mytable.key2)
上記のプログラムを実行すると、次のような出力が得られます。
rawsetはメタテーブル__newindexを使わずに値を設定します。同じようにrawgetも__indexを使わずに値を取得します。
テーブル結合演算子の動作について
2つのテーブルを+演算子で結合する簡単な例を以下に示します。
__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
上記のプログラムを実行すると、次のような出力が得られます。
2 2
3 3
4 4
5 5
6 6
この __add キーには、メタテーブルへの追加演算子 + 動作が含まれています。テーブルのキーと対応する演算子は以下の通りです。
__call
__call宣言を使用して、メソッド呼び出しの追加動作を完成させます。簡単な例では、メインテーブルの値の合計を、受け渡しテーブルで返します。
__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))
上記のプログラムを実行すると、次のような出力が得られます。
__tostring
print文の動作を変更するには、__toStringメタメソッドを使用します。簡単な例を以下に示します。
__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)
上記のプログラムを実行すると、次のような出力が得られます。
メタテーブルの機能が充実していることを知れば、使わなければ非常に煩雑になるような操作を、本当にたくさん行うことができるようになります。ですから、解釈のためのサンプルとしてさまざまなオプションを提供し、また自分自身のサンプルを作成するために、メタテーブルのメタテーブルを使った作業を行うようにしてください。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン