Lua 5.5(beta)の新機能紹介
2025/6/30に、Luaの最新バージョンであるLua 5.5のベータ版がリリースされました。
Lua 5.4.0から実に5年ぶりとなるマイナーバージョンのアップデートです。
Luaはマイナーバージョン間の互換性がないなかなかに終わっている言語なので、マイナーバージョンが上がる場合にはかなり大きな変更が行われます。
今どきLuaを好んで書いている人は少ないかも知れませんが、Luaの処理系実装をやっている身としては、Luaの最新情報は気になるところです。そして何より、Lua 5.5に関する日本語の情報が皆無...
というわけでこの記事では、Lua 5.5の新しい機能についてを紹介していきます。
globalキーワードの導入
- declarations for global variables
グローバル変数の定義を明示するためのglobalキーワードが導入されました。
-- グローバル変数としてaを定義
global a = 0
-- 初期値を指定せずに宣言だけすることも可能
global b
-- 関数も明示的にglobalにできる
global function foo()
print("foo")
end
local/globalを指定しないデフォルトの代入は、引き続きグローバル変数として扱われますが、スコープの冒頭でglobalキーワードを利用した場合、デフォルトのグローバル変数宣言は無効化されます。
X = 1 -- これはOK、グローバル変数として扱われる
do
global Y -- 明示的にYをglobalで宣言
Y = 1 -- これはglobalとして扱われる
X = 1 -- Xが宣言されていない(globalでの宣言が必要である)ためエラー
end
X = 2 -- スコープを抜けたので、デフォルトのグローバルが再度許可される
また、この変更によってLua 5.5ではglobalは予約語として扱われるようになりました。そのため、識別子としてglobalを使用することはできなくなります。
forループ変数の可変性
- for-loop variables are read only
Lua 5.4以前では、forループ(generic for)の変数は書き換えが可能でした。
t = { 1, 2, 3 }
for i in pairs(t) do
i = 10 -- 書き換えが可能
print(i)
end
Lua 5.5では、forループで宣言される変数が読み取り専用になります。よって、上のコードはLua 5.5ではエラーになります。
浮動小数点数のprintを改善
- floats are printed in decimal with enough digits to be read back correctly.
printで浮動小数点数を表示する際に、正確な値を読み取るのに十分な桁数で表示されるようになった...らしいです。
コンストラクタの改善
- more levels for constructors
この説明では何が変わったのかが全くわからないので、Luaの中の人の例を引用すると、
return {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,{1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,}}}}}}}
このようなコードはLua 5.4以前ではfunction or expression too complex" or "function or expression needs too many registersのようなエラーが起こりますが、これがLua 5.5では動作するようになりました。必要なのかな、この修正
table.createの追加
- table.create
標準ライブラリにtable.createが追加されました。シグネチャはtable.create (nseq [, nrec])で、事前に内部で割り当てられるバッファのサイズを指定してテーブルを作成することができるようになります。
local t = table.create(3)
t[1] = "a"
t[2] = "b"
t[3] = "c"
後から追加する要素が決まっている時の最適化に役立ちそうです。
utf8.offsetが文字の最後の位置を返すように
- utf8.offset returns also final position of character
Lua 5.4ではutf8.offsetは指定された文字列(Luaでは1文字=1バイト)のn番目のバイト列の開始位置のオフセットを返しましたが、Lua 5.5ではこれに加えて終了位置のオフセットを2番目の戻り値として返すようになりました。
Lua外のunmanaged文字列を扱えるように
- external strings (that use memory not managed by Lua)
C-APIから文字列を渡す際に、Lua外部で作成されたunmanagedな文字列を渡せるようになりました。これはlua_pushexternalstringで実現できます。
const char *(lua_pushexternalstring) (
lua_State *L,
const char *s,
size_t len,
lua_Alloc falloc,
void *ud);
luaL_openselectedlibs、 luaL_makeseedの追加
- new functions luaL_openselectedlibs and luaL_makeseed
C-APIにluaL_openselectedlibs、 luaL_makeseedが追加されました。
void luaL_openselectedlibs (lua_State *L, int load, int preload);
unsigned int luaL_makeseed (lua_State *L);
luaL_openselectedlibsは選択したライブラリをロードするAPIです。ビットマスクでロードするライブラリを指定できます。
luaL_makeseedはシードとして利用可能な乱数を生成するAPIです。
その他の最適化
- major collections done incrementally
- more compact arrays (large arrays use about 60% less memory)
- lua.c loads 'readline' dynamically
- static (fixed) binaries (when loading a binary chunk in memory, Lua can reuse its original memory in some of the internal structures)
- dump and undump reuse all strings
- auxiliary buffer reuses buffer when it creates final string
そのほかにも、メモリ周りの最適化が結構行われているようです。
まとめ
色々と細かい変更が入っていますが、個人的に一番大きいのはglobalキーワードの導入でしょうか。意図せずグローバル変数を汚染してしまうことが多いので、これを明示できるようになったのはありがたいです。まあLuaを使う場面ではバージョンが固定されていることが多いので、使えるようになるのかは怪しいですが...
ということで、新機能の紹介は以上です。ありがとうございました。
Discussion