入門Luaプログラミング第9章 Luaを拡張してみる(前編)

8章はアルゴリズムとかデータの扱いなので飛ばして9章、メタメソッドや自作データ型やオブジェクト指向を取り入れたりなど。急にレベルが上がった気がする…!

メタメソッド

setmetatable関数を使ってテーブルの演算子の動作を変えてみる。

> data1 = {str = "aaa"}
> data2 = {str = "bbb"}
> function my_concat(op1, op2)
>>   return op1.str .. op2.str
>> end
> setmetatable(data1, {__concat = my_concat})
> print(data1 .. data2)
aaabbb

"print(data1 .. data2)"とテーブル同士の文字列連結をしてるのに、テーブルが持っているstr同士を連結したものが表示されるように。演算子オーバーロード

新たにデータ型を作る

> point = {
>>   __add = function(op1, op2)
>>     local x, y = (op1.x + op2.x), (op1.y + op2.y)
>>     return create_point(x, y)
>>   end,
>>   __sub = function(op1, op2)
>>     local x, y = (op1.x - op2.x), (op1.y - op2.y)
>>     return create_point(x, y)
>>   end,
>> }
> function create_point(lx, ly)
>>   local p
>>   p = { x = lx or 0, y = ly or 0 }
>>   setmetatable(p, point)
>>   return p
>> end
> pt1 = create_point(1, 1)
> pt2 = create_point(30, 24)
> pt3 = pt1 + pt2
> pt4 = pt1 - pt2
> print(pt3.x .. " " .. pt3.y)
31 25
> print(pt4.x .. " " .. pt4.y)
-29 -23

ここまでするとデータ型って感じはしないなあ。もう既にオブジェクトに近い気が……
"pt1 + pt2"より"pt1.+(pt2)"ってイメージがする。どう考えてもScalaの影響です。
メタメソッドわかってないとかなり困りそうだなあ…… いろんな所で活用されてる。


ちなみに上のやつは型がただのテーブルなので、type関数を使っても

> print(type(pt1))
table

となり、どんなテーブルかわからない。代わりにgetmetatable関数を使って

> if (getmetatable(pt1) == point) then
>>   print("this is point")
>> end
this is point

とすると自作データ型でも判別できるようになる。


うー… 急にレベルが上がって疲れたので9章はここまで。続きはまた次回に。