困った時の自分用メモ

読んだ本を考察してメモったり、自分でいじった物の感想をメモったりする場。週1更新を目指します。

Luaの話~metatableの振舞を見てみた~

Luaと言えば、metatableみたいなところがあるらしいんですが、「もふねこしゅーてぃんぐ」実装時は一回も使わなかった。
ただ、やっぱりこれからもLuaを使っていこうと思っている身からすると、さすがに勉強しとかないとまずいよなという事で、簡単にテストしてみた。

▼metatableとは
http://milkpot.sakura.ne.jp/lua/lua52_manual_ja.html

2.4 – メタテーブルとメタメソッド

Luaの全ての型は、metatableというテーブルを持っているらしい
・ただし、table型以外の型のmetatableに変更を加える事は、「Lua」側からはできないらしい
・様々な演算に対して、独自の振舞を定義できる
⇒簡単に言うと、+-*/の内容を変える事ができる
・tableに関して言えば、metatableに設定されているキーバリューは、基のテーブルから見つからな かった場合は、metatableも見に行く

ざっくり、こんな感じらしい印象を受けた。

機能だけで言うなら、
前者は、C++演算子オーバーロード(で合ってったかな…?)
後者は、C++でいうポインタによる同一オブジェクト参照とか、もっと簡単な話、グローバルスタティックな値の保持みたいな感じかな。

これが、tableに対して設定可能という感じ。

▼サンプル
※LuaUnityDebugLogは、筆者が作成したUnityBindingの機能なので、Luaインタプリタとかで試す人は、ここをprintとかで置き換えてください

function LuaMain()
    -- metatable使い方1、イベント(+とか-)の定義を独自に作る
    -- ここでは、+をすると中身を乗算するようにしてみる
    -- 渡されたテーブルのvalという値を掛け合わせて返す
    local metafunc = function(a, b)
        local res = 0
        res = a.val * b.val
        return res
    end

    local base = {val=5}
    local adder = {val=2}

    setmetatable(base, {__add=metafunc})

    local calc = base + adder-- 足してるけど、内部では掛け合わせている
    LuaUnityDebugLog("RESULT:"..calc)-- calcは10
    
    -- metatable使い方2、__indexで、定義されている物を見に行くのかの検証
    local glovalAccessTable = {glovalValue1 = "引数1だよぉ", glovalValue2 = 15, glovalValue3 = {1,2,3}}
    
    local useIndexTable = {}
    setmetatable(useIndexTable, {__index=glovalAccessTable})-- これをコメントアウトすると、エラーになる

    LuaUnityDebugLog("RESULT1:"..useIndexTable.glovalValue1)-- 値は"引数1だよぉ"
    LuaUnityDebugLog("RESULT2:"..useIndexTable.glovalValue2)-- 値は15
    LuaUnityDebugLog("RESULT3:"..useIndexTable.glovalValue3[1])-- 値は1
end

▼困った点
metatableの振舞は何となく理解できたが、じゃぁ具体的にどのような場面で役に立つのか、まだピンと来ていない。
冒頭でも書いた通り、実装したアプリでは特に使用していなかったので、使わないと困るといったものでは無さそうである。
多分、なんかこう簡単に何かを実装できるようにする為に存在すると思うのだが、それがわからない。
これは、もう少し勉強と調査をしてみた方が良さそうだ。