[C][Lua]あたいが欲しいの続きです。
今度はこういう風なテーブルのデータを取る方法です。
apple = {
price = 100,
categoly = "fruit",
color = "red",
}
このようなテーブルを取るには、まずlua_getglobal()でテーブルをスタックに積んだ後、
そのテーブルを指定してlua_getfield()を使います。
このとき注意したいのが、lua_getfield()は値をスタックにおきますが、
スタックからなにも取り除かないことです。
したがって、テーブルとテーブルの値と2つがスタックに残っています。
lua_getglobal(L, "apple");
lua_getfield(L, -1, "price");
int price = lua_tointeger(L, -1);
lua_pop(L, 2);
逆に、テーブルに値を入れるにはlua_setfield()を使います。
入れるために使った値はスタックから取り除かれますが、
テーブルそのものは残っています。
lua_getglobal(L, "apple");
lua_pushinteger(L, 120);
lua_setfield(L, -2, "price");
int price = lua_tointeger(L, -1);
lua_pop(L, 1);
ただ、lua_getfield, lua_setfieldは連想配列にしか使えません。
添え字に数値を取る配列にはlua_gettable, lua_settableを使います。
// このようなLuaを読んだ後とする
// num = {"one", "two", "three"}
lua_getglobal(L, "num");
lua_pushinteger(L, 2);
lua_getfield(L, -2);
printf("%s\n, lua_tostring(L, -1));
lua_pop(L, 2);
// このプログラムをLuaで書くと以下のとおりになる
// print num[2]
// 実行結果はtwo
lua_getglobal(L, "num");
lua_pushinteger(L, 2);
lua_pushstring(L, "zwei");
lua_settable(L, -3);
lua_pop(L, 1);
// num[2] = "zwei"
lua_gettableはキーを取り除いて値を積むので、スタックの増減は0、
lua_settableはキーも値も取り除くのでスタックの増減は-2です。
どちらにしろ、テーブルは残ることに注意してください。
最後、テーブルの全要素を取る方法です。
lua_getglobal(L, "all");
lua_pushnil(L);
while (lua_next(L, -2) != 0) {
lua_pushvalue(L, -2);
printf("%s, %s\n", lua_tostring(L, -1), lua_tostring(L, -2));
lua_pop(L, 2);
}
lua_pop(L, 1);
これは、allというテーブルの全要素のキーと値を表示するプログラムです。
lua_tostringはスタックの文字列を取る関数ですが、これを実行したとき、
スタックの中身が数値だと、スタックの内容を文字列に変換してしまいます。
これではまずいので、lua_pushvalueを使ってコピーを作ったあと、
コピーに対してlua_tostringをかけることで問題を回避しています。
lua_nextが、テーブルとキーを見て、次のキーを取ってくる関数なので、
キーを数値から文字列に変換してしまうことがよくないわけです。
ですから、値の方はコピーせずそのまま使っています。