*Luaリファレンス 要注意点 ~イタレータ~ [#j915ac6a] **イタレータとクロージャ [#fbc2b632] -python 他と同じ。for in が対応していることも含めて標準的) #sh(lua){{ function values (t) local i=0 return function () i=i+1 return t[i] end end t = {10,20,30} for element in values(t) do print(element) end for element in values(t) do print(element) end }} このように2回繰り返しても、~ ちゃんとfor in 単位でクロージャがリセットされるので期待通りの挙動となる。~ ~ 以下のようにvtを用意してしまうと、当然変数寿命が維持されてしまい、~ 上手く動かなくなるので注意 #sh(lua){{ t = {10,20,30} vt = values(t) for element in vt do print(element) end for element in vt do print(element) end }} ~ **for i, v in func(a) の挙動 [#db7cbde1] >~ #sh(lua){{ for i, v in func(a) end }} などとした場合、~ forは''イタレータを繰り返す道具として、ただ一度「func, a, 制御値(iへの初期値)」を要求し''、~ ''func(a, 制御値)を繰り返す。'' ~ 例えば、ipairsを以下のように実装した時、~ #sh(lua){{ function ipairs (a) return iter, a, 0 end }} とリストを返すようにしておけば、~ 最初に、''for ... in は iter(a, 0)''を呼び出す。~ そして、''iter(a, 1)、iter(a, 2)''と順に繰り返してゆく。~ ~ pairsも同様。 #sh(lua){{ function pairs (t) return next, t, nil end }} ''next(t, k)を呼び出すと、1つ目の戻り値としてテーブルの次のキーが、2つ目の戻り値としてそのキーに関連付けられた値が返される。'' ~ ~ これらは以下のように記述可能なことを意味する。 #sh(lua){{ t = { a="ok", b="no" } for k, v in next, t, nil do print(k, v) end }} さらに言えば、リストが不足している時は、nilで補われるという多重代入の法則を利用できるので、, nilを省略して、 #sh(lua){{ t = { a="ok", b="no" } for k, v in next, t do print(k, v) end }} と記載できる。~ ~ **for ... in の展開 [#jc40b035] >''for var_1, ..., var_n in <explist> do <block> end'' は以下のように展開される。 Luaを深く使いこなすには、この展開内容を知っておく必要がある。 そうでなければ、見かけないくexplistが登場した際、その挙動を理解できないことがあるであろう。 は以下のように展開される。~ ~ Luaを深く使いこなすには、この展開内容を知っておく必要がある。~ そうでなければ、見かけないくexplistが登場した際、その挙動を理解できないことがあるであろう。~ #sh(lua){{ do local _f, _s, _var = <explist> while true do local var_1, ..., var_n = _f(_s, _var) _var = var_1 if _var == nil then break end <block> end end }} ''イテレータ関数が_f, 不変状態が_s, 制御変数の初期値がvarとすると、''~ ''制御変数は値 var_1=_f(_s, _var) var_2=_f(_s, var_1), ... var_n = _f(_s, var_n-1)のようになる。''