PHPerがLuaを触ってみて、厄介だと思った箇所 - 応用編

こんにちわ!サカナクションのライブで跳ねすぎて筋肉痛。

ごきげんよう。私です。

PHPerがLuaを触ってみて、厄介だと思った箇所 - 応用編

前回の続きLuaオブジェクト指向を使う方法

まずは、テーブルとメタテーブルの使い方を覚える必要がある。





テーブル



Luaにはまとめてデータを扱う仕組みとしてテーブルと呼ばれるものがある。

PHPだと連想配列とかC言語で言うところの構造体っぽいもの。



テーブル作成方法

table = {}



値の入れ方

table["test"] = "hoge"
table = {test1 = "hoge", test2 = "fuga"}
table.insert(table, "moge")





イテレータ用関数



テーブルのキーが文字列の場合は、pairs関数

数字の場合は、ipairs関数を使用する。


t = {}
t["test1"] = "hoge"
t["test2"] = "fuga"
t["test3"] = "moge"

for i, ver in pairs(t) do
	print(ver)
end
hoge
fuga
moge





メタテーブル



メタテーブルを利用するとテーブルや演算子の役割を置き換えることができる。

メタテーブルを活用すれば,テーブルがあたかもクラスであるかのように扱うこともできます。



メタテーブルには __で始まる文字列が予め用意されていて、

この文字列をイベント、値をメタメソッドと言いオブジェクト(テーブルとか値)の

動作をいくつかの面で変えることが出来る。(リファレンスみてください。)



テーブルのメタテーブルは setmetatable関数で変更することが出来る。




t1 = {value = 20}
t2 = {value = 30}

mt = {
   __add = function (l , r)
	    return l.value + r.value
	 end
}

\-- t1テーブルをmt定義に置き換える。
setmetatable(t1, mt)

print(t1 + t2)
\-- __add は + 演算が実行されるときに呼ばれる。便利ー!
⇒ 50





クラス



Lua自体にクラスは無いが、テーブルとメタテーブルを使うことで

オブジェクト指向で記述することができる。





プロトタイプベースオブジェクト指向



Luaでは以下のように値、関数を呼ぶことが出来る。

テーブル内の値を呼ぶ際に「table["key"]」 とかくところを 「table.key」

テーブル内の関数を呼ぶ際に「table.key(value)」とかくところを「table:key(value)」


\-- オブジェクト作成
Dog = { name = "Jiro" age = 3 showProfile = function(self) prof = string.format("name=%s, age=%d", self.name, self.age) print(prof) end } \-- showProfile メソッドを呼ぶ Dog:showProfile()





クラス定義



Luaにはnew演算子が用意されていないので

newと同じような動作を行うメソッドを用意する必要がある。



Luaにはオブジェクト指向の継承を実現する仕組みが用意されている。

継承を実現するために、メタテーブルには __indexというイベントがる。

メタテーブルの __indexにスーパークラス(継承元のクラス)を指定することで

継承を実現することができる。



__indexにスーパークラスのオブジェクトを設定すると

そのオブジェクト自身のキーを探したあと、スーパークラスのオブジェクトの

プロパティを探しに行くようになる。





無名関数を使う際に以下の記述でもできる。

function table-name:function-name ~ end



table-name.element = function() ~ end





例:クラス

Point = {}

function Point:new()
	local t = {}

	t.x = 0
	t.y = 0

	\-- 自分自身を継承する。
	setmetatable(t, {__index=Point})
	return t
end

function Point:set(dx, dy)
	self.x = dx
	self.y = dy
end

\-- 呼び出し
pt1 = Point:new()
pt1:set(10,10)





例 : 継承

\-- 親クラス
Animal = {}
Animal.name = "unknown"
Animal.showProfile = function(self)
	print("*** profile")
	print("name="..self.name)
end

\-- 小クラス
Dog = {}
Dog.new = function (name) 
	local obj = {}
	obj.name = name
	setmetatable(obj,{__index=Animal})
	return obj
end

\-- 呼び出し
jiro = Dog.new("jiro")
jiro:showProfile()







これで、ある程度の基礎は掴んだつもり...

Luaはテーブル万歳なんだなヽ(^。^)ノ

でも、逆にシンプルで全然嫌いじゃない。むしろ好き。

あとは下の本を読むか実際のプロジェクトのコードを読んでいって慣れていこうと思います。