エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

Lua 5.1とLua5.2の違い

Lua側から見た場合の差異。C言語向けのAPIの差異はいずれまた。


詳しくはリファンレスマニュアルの「Incompatibilities with the Previous Version」を参照してみてください。

言語構造の変更

制御構造に変更がありました。gotoの追加です。

gotoはジャンプ先のラベルの名前を指定しますが、ラベルは名前の前後それぞれにコロンを2つ繋げたものになります。

goto foo

-- ...

::foo::

削除されたLua 5.1の基本関数

次の関数が削除されました

関数 理由
getfenv コンセプト変更にともない削除
setfenv コンセプト変更にともない削除
module コンセプト変更にともない不要になった
loadstring loadに統合
unpack table操作関数に組み込まれた


コンセプトについてはマニュアルに次のようにあります。詳細はマニュアルを参照してみてください(要はわたしはまだきちんと把握できていないということです…)。

The concept of environment changed. Only Lua functions have environments. To set the environment of a Lua function, use the variable _ENV or the function load.


Lua 5.2 Reference Manual 8.1 Changes in the Language

追加された基本関数

rawlen関数が追加されました。

テーブルや文字列の長さを返す演算子(#演算子)が従来からありす。この演算子はメタテーブルの__lenメタメソッドを呼び出します。
一方rawlen関数は__lenメタメソッドを使わずに長さを取得します。

$ ../src/lua
Lua 5.2.0  Copyright (C) 1994-2011 Lua.org, PUC-Rio
> a = {}
> setmetatable(a, { __len = function() return 10 end })
> print(#a)
10
> print(rawlen(a))
0

追加されたライブラリ

32ビットデータのビット演算ライブラリが追加されました。組込み屋にはありがたい追加。組込みソフトでなくても、通信パケットの解析などでは重宝します。
それぞれ詳しくはマニュアルの「Bitwise Operations」を参照してみてください。

bit32.arshift 算術右シフト
bit32.band ビット論理積
bit32.bnot ビット論理否定
bit32.bor ビット論理和
bit32.btest ビット論理積
bit32.bxor ビット排他的論理和
bit32.extract ビット列の切り出し
bit32.lrotate 左回転
bit32.lshift 左シフト
bit32.replace ビット列の置き換え
bit32.rrotate 右回転
bit32.rshift 右シフト

bit32.bandbit32.borbit32.btestbit32.bxorの引数は可変長で複数の値を同時に演算することができます。

bit32.bandbit32.btestの違いは、前者は演算結果の数値を返すのに対し、後者は演算結果の数値が0ならばfalseを0以外ならばtrueを返す、という点です。

変更されたライブラリ

デバッグライブラリ

コンセプトの変更にともない、デバッグライブラリの関数の一部が置き換わっています。
デバッグライブラリを使ったことがないので、詳しくはデバッグライブラリのマニュアルへ…。

Lua 5.1 Lua 5.2
debug.getfenv debug.getuservalue
debug.setfenv debug.setuservalue
debug.upvalueid debug.upvaluejoin
数学ライブラリ

math.log10が削除になっています。これはmath.logに底を指定する第2引数が追加されたことで、底が10の関数を別途用意しておく必要がなくなったため。

パッケージライブラリ
  • 追加:パッケージのコンパイル時の設定を保持しているpackage.config変数が追加されています。
  • 追加:パスを検索するpackage.searchpathが追加されています。
  • 名称変更:package.loadersからpackage.searchersへ名称が変更されています。
  • 削除:package.seeallが削除されています。


package.searchpathLuaのライブラリ以外でも利用できるみたいです。下記の例は指定したパスが見つからなかった場合ですが、見つかった場合は“../foo.txt”というようにパスを返します。以外と使い道がありそう。

> print(package.searchpath("foo", "./?.txt;../?.txt;../src/?.txt"))
nil
    no file './foo.txt'
    no file '../foo.txt'
    no file '../src/foo.txt'
テーブルライブラリ
  • 追加:table.unpackが基本関数からこちらに移動しています。
  • 追加:table.packが追加になっています。
  • 削除:table.maxnが削除になっています。理由は特別に関数を用意しなくても目的を果たせるから。


table.unpackは5.1でも単独の関数としてありましたが、5.2でテーブルのライブラリに移動になりました。

> t = {1,2,3}
> a,b,c = table.unpack(t)
> print(a,b,c)
1   2   3


table.packtable.unpackと対にするために追加されたような雰囲気ですが、何か微妙。

> t = table.pack(1,2,3)
> for k, v in pairs(t) do print(k, v) end
1   1
2   2
3   3
n   3

table.packを使うと、パックした要素数を格納するnという要素が含まれます。便利なのか邪魔なのか不明。要素がわかっている場合にはt = {1,2,3}という書き方ができるので、返す値の数が不明な関数の結果をテーブルにしたいときなど利用シーンは限られる気がしてます。