Luaとオブジェクト指向2

開発が本当にちまちまとしか進まないのでLuaについてここまでで分かったことの中からいくらかをまとめてみようと思います。


概要
トップページだけ日本語訳したものがあるみたいです。
http://www.lua.jp/
インタプリタ言語インタプリタ言語言ってるけど仮想レジスタマシンのバイトコードを実行する形式なんだからJavaC#とかと一緒でしょ?とか思ったけど実際その通りで、
ソースコード→(コンパイル)→バイトコード(仮想機械語)→(これをインタプリタ実行)→実機械語レベル
まあ結局Javaとかもコンパイラ言語でありインタプリタ言語でもあったねという話でしかなかった。luaコンパイラとか普通にあるしね。バイトコードまで変換するだけでJavaコンパイラと一緒。
こういうインタプリタ形式のスクリプト言語としては速度では最高水準。フォトショとかwiiウェアのなんかとかPS3のなんかのゲームだとかで色々使われてるみたい。
言語仕様全体をだいたいつかんだところでの感想は次の引用文に尽きる。

Luaの設計の基本コンセプトは、言語自体に様々な機能を装えるのではなく、機能を実現できる巧妙な仕掛けを提供することです。

「仕掛け」自体は少ないものの、逆に少ないそれを覚えれば本当に何でもできそう。欠点としては…例えばオブジェクト指向を例に挙げれば、「Luaではオブジェクト指向を学べない」ってことかな。あの言語でこう書いてたものをLuaで実現するにはこれをこうしてこうだ、みたいな。あと同じことをするのにいくつもアプローチができて複数人で書く場合は書き方の統一が必須すぎる。


クラス
書きすぎたか…。とにかくオブジェクト指向について早く書き始めよう。

ParentClass = {}

-- ParentClass.new = function ... end
function ParentClass.new(name)
  local obj = {}
  obj.name = name
  setmetatable(obj, {__index = ParentClass}
  return obj
end

-- ParentClass.print_info = function(self) ... end
function ParentClass:print_info()
  print(self.name)
end

local obj1 = ParentClass.new("Toki")
-- obj1.print_info(obj1)
-- ParentClass.print_info(obj1) (__indexによる)
obj1:print_info()

フィールドとメソッド相当のことはこんな感じです。フィールドはコンストラクタnewで作るときに作成して初期化します。メソッドはnewで作られるオブジェクトのメタテーブル__indexにParentClassを設定しておき、obj.methodと指定されたときにParentClassへ探しに行くようにします。


継承

ChildClass = {}
setmetatable(ChildClass, {__index = ParentClass})

function ChildClass.new(name, rank)
  local obj = ParentClass.new(name)
  obj.rank = rank
  setmetatable(obj, {__index = ChildClass})
  return obj
end

-- override
function ChildClass:print_info()
  -- call superclass method
  ParentClass.print_info(self)
  print(self.rank)
end

local obj2 = ChildClass.new("toki", 1)
obj2:print_info()

まずコンストラクタでは、ParentClass.newを使ってスーパークラスのフィールドを作成・初期化し、そのオブジェクトに新たなフィールドを追加します。また、メタテーブルを__indexがChildであるものに取り換えます。ChildClassのメタテーブルの__indexにはParentClassを設定します。これでobj2→ChildClass→ParentClassの検索チェーンができます。メソッドのオーバーライドはChildClassに同名のキーに関数を設定。スーパークラスメソッドの呼び出しはまあ無理にこれで。ChildClass.superとか決まった名前にParentClassを入れておいてChildClass.super.print_info()した方がいいかもしれません。


資料について
私が持っている本はこれだけです。

Programming in LuaっていうのがLuaの開発者による書籍で、いいんじゃないかと思います。
オフィシャルマニュアルの非公式の日本語訳。具体的な活用例やよいコードの例、イディオムに欠けるが(翻訳プロセスがかかっているもののとりあえず)一次情報源として信頼できます。
http://sugarpot.sakura.ne.jp/yuno/html/lua51_manual_ja.html
多分なんだかんだのいろいろな情報が一番充実してる気がする。英語だけど。
http://lua-users.org/wiki/