Lua のテーブルと配列のしくみ

This entry was posted by on Monday, 28 May, 2007

PHPの配列のキーについて調べてみるという話をみました。 PHP のこの話は前にもどこかで読んだことがないわけではなく、そのたびに「キモいねえ」と思うわけですが、幸いにして PHP で組むはめになったことがないので(正確には二度ほどあったが、どちらも自分にコントロール権があったので、ぜんぶ Ruby で書きなおした)、個人的にはさほどの興味はないのでした。

さて、ハッシュと配列が同一視されているプログラミング言語というと、わたしは Lua を思い出します。

Lua は「テーブル指向」の言語で、とにかくありとあらゆるデータ構造を「テーブル」(ようするにハッシュだ)で表現します。 t['key'] を t.key と表記できたり、 function というキーワードで無名関数も作れたりとちょっと JavaScript に似ている気がします。……ってそれくらいか。わたしはわりと好きですね。あんまり使っていませんが。

さて、 Lua はテーブル指向でありまして、配列も「テーブル」というデータを使っています。ちなみにテーブルのキーには nil を除く任意のデータが使えますが、物理的な同等性で比較されるので注意が必要です。実用上は文字列と数値以外には使われないと思います。

まず、 Lua ではキーに数値と文字列を使っても混同が起きません。まあ、当然だと思いますが。

面白いのは、 Lua は配列としては順序を記憶しているがハッシュとしては順序を記憶していないことです。 Lua ではテーブルの各要素をなめるための for ループ構文がありますが、まず整数のキーをその順番に処理し、残りの要素があればそれをよくわからない順序で処理する、という流れになります(数値パートだけを処理するようなこともできる)。

そのようになっているのはなぜかというと、ようするにテーブルというのは実態としては、配列とハッシュの組み合わせになっているのだね。十分小さな整数がキーのときは配列パートに組み入れられ、そうでない場合にはハッシュに放り込まれるようになっていると。で for ループではまず配列パートをなめてからハッシュパートに取りかかるため、そのような処理になるというわけです。したがって、キーが整数でも巨大である場合にはハッシュになることがあります(リハッシュが発生した段階で配列パートに戻ることもある)。

そこまで頑張るくらいなら配列とハッシュくらいは分けてもよかったんじゃない?という気もするんですが(じっさい類似の組み込み言語と言われている Squirrel は配列とハッシュが分かれているらしい)、面白いことをやっているなということで紹介してみました。

ところで Lua プログラミングの名高い落とし穴として「配列のインデックスは1から始まる」というのがあります。キーに0は指定できるんですが、これはハッシュテーブルに放り込まれるのですね。むかしは0とnilが同一視されていたとかそういう系なのですかね。理由はよくわかりません。

そういうわけで、次のように書くと、

a = {} a[1] = 1 a[2] = 2 a[0] = 0 a['0'] = ‘zero’ for k, v in pairs(a) do io.write(k..""..v.."\n") end

結果はこんな感じで、

1 1 2 2 0 0 0 zero

0が三番目(わかりづらいですが最後のが '0' のペア) 。うーむ。配列パートだけを使う ipairs を使うと、

> for k, v in ipairs(a) do io.write(k..""..v.."\n") end 1 1 2 2

0がありません。

というわけで Lua でした。

Comments are closed.