HaxeでluaのネイティブコードにArrayを公開するときの作法
ここで自分が質問してたことのまとめです。
https://github.com/HaxeFoundation/haxe/issues/9512
問題点
Array<T>をluaのネイティブコードに向けて公開したとき、
Haxeは0-indexedなのに対し、luaは1-indexedなので、0番目の要素が(取り方によっては)取れない。
@:expose
class Sample {
static function main(): Array<Int> {
return [10, 20, 30];
}
}fromHaxe = require 'sample'
print('native')
local a = { 10, 20, 30 }
for i, m in ipairs(a) do
print(string.format("%d: %s", i, m))
end
print('from haxe')
local b = fromHaxe.Sample.main()
for i, m in ipairs(b) do
print(string.format("%d: %s", i, m))
end実行すると、頭の10が失われていることが分かる。
haxe -main Sample -lua sample.lua && lua sample2.lua
native
1: 10
2: 20
3: 30
from haxe
1: 20
2: 30解決策
luaと他言語でreturnを分ける
luaにはlua.Tableとして、他言語にはArrayとして公開する。
#if lua
return lua.Table.fromArray(data);
#else
return data;
#end暗黙的な型変換を利用して勝手によしなにする
import lua.Table;
import lua.PairTools;
@:forward abstract LuaArray<T>(Table<Int, T>) from Table<Int, T> to Table<Int, T> {
@:from static inline function fromArray<T>(array: Array<T>): LuaArray<T> {
return Table.fromArray(array);
}
@:to function toArray(): Array<T> {
final array = new Array<T>();
PairTools.ipairsEach(this, function(index, element) {
array.push(element);
});
return array;
}
}static function main2(): LuaArray<Int> {
var data = [10, 20, 30]; // Array<int>
return data;
}疑問
Q
(標準ライブラリがLuaに対してArrayを返してくることに対して)
標準ライブラリは、NativeCodeで使いやすいインターフェイスであることが期待されているのではないですか?
また、そのあたりのポリシーが参照できるものはありますか?
A
Haxe全体としてのポリシーが参照出来るページなどはありません。
また、ターゲットによってメンテナが違うので見解やスタイルが異なることも考えられます。
歴史的な理由で変更できない、などの可能性もあります。