入門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章はここまで。続きはまた次回に。