ネームスペース風の改造

このエントリ(http://d.hatena.ne.jp/tattyu/20050927#p3)で書いたやり方なんですけど、
FarCryLuaを眺めていたらよりネームスペースのように書ける事に気がついた。

--lua_test.lua
lua_test = {
	abc = 10,
	OnUpdate = function(this)
		print("call lua_test::OnUpdate(" .. this.abc .. "\n")
	end,
}


これは以前のやりかたとほぼ一緒で、
thisはCの方で明示的にスタックに積んで引数としてlua_testを渡してるんだけど、
以下のように書いても全く同じ挙動をする事がが判明

--lua_test.lua
lua_test = {
	abc = 10,
}

function lua_test:OnUpdate()
	print("call lua_test::OnUpdate(" .. self.abc .. "\n")
end


":"を使うと、指定されたリストに":"以下の名前で関数を登録し、さらに隠し引数としてselfが渡されるようになる。
さらに上記の引数のthisを省略して変わりに予約語のselfでアクセスが可能になるんです。


気をつけなきゃいけないのはこの関数をCから呼び出す時は明示的にselfをスタックに積まなければならない事だろう。これはまぁ以前のようなソースが動いてる環境なら全くC側に手を入れる必要は無いので気にしなくてもいいんだろうね。
シンタクスシュガーってやつだ。


で、別に関数でselfなんかつかわねーや、いらねーやって時は":"の代わりに"."を使うことができる。
この場合はC側で呼び出す場合にもselfを渡さなくても良くなる。


比べてみると、関数全てにlua_test:をつけるのがだるい!って場合は以前の書き方がいいと思う。でもthisを明示しなきゃいけなかったり、リストの内部だから関数のendの後ろに","をつけなきゃいけなかったりと一長一短な感じなのでお好きな方を使うといいと思います。


ちなみにFarCryではネームスペースは固定みたいでMissionという名前のリストを使っていた。
local指定してないので多分別の機能を持つLuaをさらに読み込もうとするときに名前が衝突すると見た。


ということでFarCryは1ステージ1インスタンスっぽい。


気がする。