プログラミング言語 Lua  その2

このエントリーをはてなブックマークに追加
952デフォルトの名無しさん:2006/10/09(月) 18:11:31
俺の気持ちを嘘だといわれても困るのですが・・・・
953デフォルトの名無しさん:2006/10/09(月) 18:12:31
>>951
お前は文が読めないのか???
954デフォルトの名無しさん:2006/10/09(月) 18:21:03
Cしか知らなくてポインタが使えない言語もあること知らないだけだろ。
955デフォルトの名無しさん:2006/10/09(月) 18:24:48
あれだな、Luaを導入する人の開発記を見てると
「スタック使いにくい」と言って独自のラッパーを作る香具師が多い。

ただその後「スタック簡単じゃんラッパいらんな」とAPI直接使うようになる香具師と
スタック使いにくいと言い続ける香具師に別れる。
956デフォルトの名無しさん:2006/10/09(月) 18:28:22
・「スタック簡単じゃんラッパいらんな」とAPI直接使うようになる香具師
・スタック使いにくいと言い続ける香具師

の例を頼む



というか、お前今の時代に「香具師」って・・・
その超おっさん感をなんとかしろ。
957デフォルトの名無しさん:2006/10/09(月) 18:29:37
別にどっちが良い悪いなんて言ってないよ。
全部自分への悪口に見えるのかい?
958デフォルトの名無しさん:2006/10/09(月) 18:31:38
>>957
意味不明すぎ
959デフォルトの名無しさん:2006/10/09(月) 18:36:42
ラッパよりも、#defineで定義した俺様マクロに心引かれる俺様が来ましたよ。
960デフォルトの名無しさん:2006/10/09(月) 18:43:17
つまり、MFC使いやすい!嘘つけ!という議論ですね!
961デフォルトの名無しさん:2006/10/09(月) 18:51:34
C/C++から簡単に読めるように、設定ファイル用途のLuaを呼び出した後、
設定ファイル前処理用Luaを呼び出すのが正解。
スタックが面倒なら、Luaでやれることは全部Luaにやらせようぜ。
962デフォルトの名無しさん:2006/10/09(月) 19:13:20
962が禿しく正論
963デフォルトの名無しさん:2006/10/09(月) 19:15:40
>>962
自己完結してるな
964デフォルトの名無しさん:2006/10/09(月) 19:42:13
自分の好きに使えばいいじゃん。
965デフォルトの名無しさん:2006/10/09(月) 20:37:30
テーブルの挙動がわからん
Struct={}
file_read(Struct,"data.txt")

function file_read(table,file_name)
local get_buf=""
local k=1
local key=0
local v=0
local file_num
file_num=_FOPEN(file_name,"r")

while get_buf==nil do
_FGETS(file_num,get_buf)
for key,v in string.gfind(get_buf, "([%w]+)=([-]?[%w]+)") do
table[k][tonumber(key)]=tonumber(v)
end
k=k+1
end
_FCLOSE(file_num)
end

読み込むデータ
[1]:{[0]=2,[1]=2,[2]=8,[3]=17,[4]=10}
[2]:{[0]=3,[1]=3,[2]=2,[3]=7,[4]=100}
[3]:{[0]=4,[1]=4,[2]=41,[3]=7,[4]=50}
[4]:{[0]=5,[1]=5,[2]=40,[3]=7,[4]=10}
[5]:{[0]=6,[1]=6,[2]=42,[3]=7,[4]=30}
[6]:{[0]=1,[1]=1,[2]=41,[3]=7,[4]=30}

何か俺間違えてる?
966デフォルトの名無しさん:2006/10/10(火) 15:16:38
>935
を繰り返しを使ったコードで書き直してみた。ちょっとごちゃごちゃしているけど。

function rnext2(t, keys)
 keys = keys or {}
 local k, v
 local ks, c = {t}, (#keys > 1) and #keys or 1
 for i = 2, c do
  ks[i] = ks[i-1][keys[i-1]]
 end
 k, v = next(ks[c], keys[c])
 while (k == nil) and (c > 1) do
  ks[c], keys[c], c = nil, nil, c-1
  k, v = next(ks[c], keys[c])
 end
 if k == nil then return nil end
 keys[c] = k
 while type(v) == 'table' do
  k, v = next(v, nil)
  keys[#keys+1] = k
 end
 return keys, v
end

935 だと keys は連結リストだが、こっちは1つのテーブルを配列っぽく使ってる。
967デフォルトの名無しさん:2006/10/10(火) 18:00:54
io.readとか使ってデータを読み込むとなると一行ずつだが
dofileでチャンクごと読み込むと楽だよな

dofileで読み込むとglobalになるから好ましくないんだっけ?
968デフォルトの名無しさん:2006/10/10(火) 19:26:50
globalを汚さないdofileはこんな感じで良いのかな?

function envdofile(filename)
 local c = loadfile(filename)
 local e = {}
 local m = getmetatable(e) or {}
 m.__index = getfenv(c) or _G
 setmetatable(e, m)
 setfenv(c, e)
 return e, c()
end

使い方

-- a.lua
c = envdofile("b.lua")
print(b) -- nil
print(c.b) -- 10

-- b.lua
b = 10
print(b) -- 10
969デフォルトの名無しさん:2006/10/10(火) 20:24:10
HSPに愛想が尽きたのでLuaでゲームを作りたいです。
LuaGLの存在は知っていますが、LuaからGLUTを呼ぶためのライブラリは既にありますか?
むしろ作るべきですか?
970デフォルトの名無しさん:2006/10/10(火) 21:19:19
lua-users wikiに作りかけのがあったはず。
971デフォルトの名無しさん:2006/10/10(火) 21:43:25
LuaScene
972デフォルトの名無しさん:2006/10/12(木) 07:04:08
Google code search
973デフォルトの名無しさん:2006/10/12(木) 08:24:26
とりあえず

io.readAll io.writeAll
io.readCSV io.writeCSV
io.readTab io.writeTab
table.marge table.unmarge
table.dump table.save table.load
stack.dump

があったら便利だと思った。
974デフォルトの名無しさん:2006/10/12(木) 18:27:25
だいたい半分くらい書き終わりました。
975デフォルトの名無しさん:2006/10/12(木) 20:30:08
テーブルに値を入れるのに入れ子にすると大変だから

["document"]["body"]["color"]=256

["document:body:color"]=256

みたいにすればファイルへのセーブ・ファイルからのロードも楽になるが・・・
976デフォルトの名無しさん:2006/10/12(木) 20:32:03
オマエ・チョット・アホ・デス・カァ
977デフォルトの名無しさん:2006/10/12(木) 21:07:16
ヒント: document.body.color=256
978table.dumpを書いてみました:2006/10/12(木) 23:18:50
print((string.gsub(string.gsub(--[[Lua5.1用table.dump関数を出力]] [[
table._dump_temp = nil#function lua_table_dump(src, i)# if src == nil@
then return nil end# if i == nil or type(i) == "string" then --"i" i@
s `tag' on top level call# if i == nil then i = "t" end# if type@
(src)=="table" then# table._dump_temp = i .. "={\n"# lua_tab@
le_dump(src, 1)# table._dump_temp = table._dump_temp .. "}\n"# @
local result = table._dump_temp# table._dump_temp = nil# @
return result# else# return nil --illegal arguments# end# @
else --"i" is indent on recursive call# local dst = {}# local in@
dent = string.rep(" ", i)# for k,v in pairs(src) do# if type(@
k) == "number" then k = "[" .. k .. "]" end# if v==table._dump_te@
mp then# --do nothing# elseif type(v)=="table" then# @
table._dump_temp = table._dump_temp .. indent .. k .. "={\n"# @
i = i + 1# lua_table_dump(v,i)# table._dump_temp = tabl@
e._dump_temp .. indent .. "},\n"# elseif type(v)=="string" then# @
table._dump_temp = table._dump_temp .. indent .. k .. "=\"" .. @
v .. "\",\n"# else# table._dump_temp = table._dump_temp ..@
indent .. k .. "=" .. tostring(v) .. ",\n"# end# end# end#end#@
table.dump = lua_table_dump#]],"@\n",""),"#","\n")))
979978:2006/10/12(木) 23:35:18
えーと、>>978をLua5.1のLua.exeに食わせるとコードを吐きます。
ちょっと1レスに収まりきらなかったので・・・。

使い方はこんな感じです。

a = {A="A",B={b="b","d"},42} --複雑なテーブル
dump = table.dump(a, "a")
print(dump)
--(ここで dump を save.txt に保存したと仮定)
a = nil
dofile("save.txt") --読み込み
print(table.dump(a, "a"))

変なとこあったら教えてください。
980デフォルトの名無しさん:2006/10/13(金) 00:00:09
コードを見てないからなんなんだが、
a = {A='a'}
a.next = a
みたいな循環構造のテーブルを渡した場合はどうしてる?
981978:2006/10/13(金) 07:46:15
>>980
(((( ;゚Д゚)))ガクガクブルブル
982デフォルトの名無しさん:2006/10/13(金) 14:01:28
>>980-981
ワラタ
983デフォルトの名無しさん:2006/10/13(金) 15:24:08
>>926,935 も循環参照は考えてなさそうだな。
984デフォルトの名無しさん:2006/10/13(金) 17:37:23
try-catch構文(もどき)

exception=setmetatable({throw=error},{__newindex=
function(t,k,v)if k=="catch"then xpcall(t.try,v)
else rawset(t,k,v)end end})

exception.try                         =function()
 print("foo")
 exception.throw("(^^)")
 print("bar")                        end function
exception.catch(err)
 print("error : "..err)
end
985デフォルトの名無しさん:2006/10/13(金) 19:55:07
finallyもぜひ
986デフォルトの名無しさん:2006/10/13(金) 20:26:48
>>983
考えてみると循環参照やら function、thread、userdata の復元やら、テーブルのシリアライズには
色々と問題がありますね・・・。あと、循環参照でなくても

d = { A="A" }
t = { d, d }

とかいう構造だと、

t = { [1]={ A="A" }, [2]={ A="A" } }

とは等価ではなく、

do
 local d001 = { A="A" }
 t = { [1]=d001, [2]=d001 }
end

みたいにダンプしてあげないと復元できないし・・・。
987デフォルトの名無しさん:2006/10/13(金) 22:42:29
988デフォルトの名無しさん:2006/10/13(金) 23:08:19
12.1.2のって

NIL
BOOLEAN
FUNCTION
USERDATA
LIGHTUSERDATA
THREAD

の場合はどうしてるんだ?
文字列に変換出来るのだろうか?
989デフォルトの名無しさん:2006/10/13(金) 23:17:14
926 のを循環参照に対応させてみた。
function each(t)
 local cache = {}
 local function e(t)
  cache[t] = true
  local k, v = next(t)
  while k do
   if cache[v] then
   elseif type(v) == "table" then
    e(v)
   else
    coroutine.yield(v)
   end
   k, v = next(t, k)
  end
 end
 return coroutine.wrap(e), t
end

いちおう動いてるっぽい。
990デフォルトの名無しさん:2006/10/13(金) 23:42:06
>>988
error("cannot save a " .. type(value))

だと思う。
991デフォルトの名無しさん:2006/10/14(土) 00:43:51
schemeと似てるな
992デフォルトの名無しさん:2006/10/14(土) 10:08:44
順序が不定だと困る場面がありそうなので、キー順に巡回する spairs 関数を書いてみた。
使い方は Using: の行を参照。 t={A="a", B="b", [1]="c", [2]="d"} などの文字列数字混在でも可。

--compare many types (over spec...)
function table_lt_event(op1, op2)
 local type1, type2 = type(op1), type(op2)
 if type1 ~= type2 then --cmp type
  return type1 < type2
 elseif type1 == "number" and type2 == "number"
   or type1 == "string" and type2 == "string" then
  return op1 < op2 --default
 elseif type1 == "boolean" and type2 == "boolean" then
  return op1 == true
 else
  return tostring(op1) < tostring(op2) --cmp address
 end
end

(続く)
993992:2006/10/14(土) 10:10:14
(続き)

--sorted keys
-- Using: for i, k in pairs(table.keys(t)) do ... end
function lua_table_keys(t)
 local keys = {}
 for k in pairs(t) do
  table.insert(keys, k)
 end
 table.sort(keys, table_lt_event)
 return keys
end

--sorted pairs
-- Using: for k, v in spairs(t) do ... end
function lua_table_spairs(t)
 local k = {}
 local function e(t)
  for i, v in pairs(lua_table_keys(t)) do
   coroutine.yield(v, t[v])
  end
 end
 return coroutine.wrap(e), t
end

table.keys = lua_table_keys
spairs = lua_table_spairs -- or table.spairs = lua_table_spairs
994984:2006/10/14(土) 10:54:05
finallyにも対応したつもり
ただしtry-catch-finallyとつなげることはできない

exception=setmetatable({throw=error},{__newindex=
function(t,k,v)if k=="catch"then xpcall(t.try,v)
elseif k=="finally"then(function(e,m,...)v(e,m,
...)if not e then error(m,0)end end)(pcall(t.try))
else rawset(t,k,v)end end})

exception.try               =function()
 exception.throw("hogehoge")    end
exception.finally             =function()
 print("finally")
end
995デフォルトの名無しさん:2006/10/14(土) 11:26:26
つなげられなくても
try
 try
 catch
 end
finally
end
とできれば問題ないっす
996デフォルトの名無しさん:2006/10/14(土) 12:11:29
2.5より前のPython方式ですな。
997デフォルトの名無しさん:2006/10/14(土) 12:22:18
>>995
994のコードを見る限り、それは不可能だぞ。
998984:2006/10/14(土) 12:27:01
これでどうだ?

exception=setmetatable({throw=error},{__newindex=
function(t,k,v)if k=="catch"then xpcall(t.try,v)
elseif k=="finally"then local m,e e=xpcall(t.try,
function(e)m=e v(false,e)end)if e then v(true)
else error(m,0)end else rawset(t,k,v)end end})
999デフォルトの名無しさん:2006/10/14(土) 12:44:25
ところで次スレは?
1000デフォルトの名無しさん:2006/10/14(土) 13:06:30
1000げと
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。