引き続き、Luaリファレンスマニュアルの日本語訳でお勉強です。

長さ演算子

演算子はおおむね普通。とおもっていたら、テーブルに対する長さ演算子の振る舞いにちょっとびっくりしました。

長さ演算子は単項の#です。
文字列に適用した場合はバイト数。

テーブルに適用した場合は、テーブルをtとすると: t[n] ~= nilでt[n + 1] = nilになるようなnと定義されているそうで、そうするとどうなるのか、以下実例をあげてみましょう。

t1 = {"a", "b", "c"}
#t1 -- 値は3
t2 = {value1 = "a", value2 = "b", value3 = "c" }
#t2 -- 値は0
t3 = {value1 = "a", "b", value3 = "c" }
#t3 -- 値は1
t4 = {value1= "a", [22]="b", value3="c" }
#t4 -- 値は0
t5 = {value1 = "a", "b", [2]="c"}
#t5 -- 値は2

なんでこうなるかは、リファレンスマニュアルちゃんと読むとわかります。でもこれじゃ、連想配列に対する長さ演算子としては使い物になりませんね。テーブルに対するイテレータが作れればまあ実用上問題ない、んだろうけど、イテレータってどうやって作るんだろう。

関数呼び出し構文

v:name(...)の意味は、v.name(v, ...)とほぼ同じ。ただし、v:nameの場合はvの評価は一度しか行われない。v:nameの書式を「メソッド」と呼ぶ。関数定義で:構文使っている場合はやはり「メソッド定義」と呼ばれて、暗黙の第一引数はselfという名前で参照できる。

引数の形式は、()でも、テーブルコンストラクタでも、文字列でもよい。

return 関数呼び出し ってやると、末尾再帰最適化するそうな。あとで実験してみましょう。