Pairsの話
Luaで自前でイテレーションしたい時がたまにある。
要素がnilの時の扱いがnextとpairsとかで違うからだ。
サイズを取得するときも最初にnilを発見した所までのサイズしか返さないので、適当にnilを突っ込んでるの忘れてるとよく分からないバグに遭遇したりする。
そのたびに自前で実装しよう!とか思うんだけど、なくてもまぁ困るものではないし実装がめんどくさそうなので無視してきたわけですよ。
最近ちょっとばかし余裕が出来たので実装してみた。
これであってるのかな。
それにしてもクロージャーすげぇぜ!
-- 自前pairsの実装テスト -- "end"という文字を発見するまでkeyが1ずつ増える function my_pairs( table_name ) local key = 1 -- 2つの値を返すイテレータ関数を返す. -- 終わらすときはnil返せばいいのかな。。。 return function() if ( table_name[key] == "end" ) then return nil,nil else local k = key key = key + 1 return k,table_name[k] end end end -- 適当なテーブルを渡してテスト -- 別にこういう使い方ならpairsでも大して変わらんね do local my_lst = { "my", "name", "is", nil, "tattyu", "end", } for i,v in my_pairs(my_lst) do if ( v ) then io.write(v.." ") else io.write("\n") end end io.write("\n") end
結果
my name is tattyu
コメントにも書いてるけどこういう使い方ならpairsを使ったほうがよい。
nilで終わらせたい場合はipairsを使えばいいらしい。
たとえばitrの中で関数呼んだりするようにしたいときとかいいんじゃなかろうか。
呼び出してる側の意図しない所で関数よばれたりしてバグりそうだけどw
function my_pairs( table_name, func ) func = func or function( v ) return v end local key = 1 -- 2つの値を返すイテレータ関数を返す. -- 終わらすときはnil返せばいいのかな。。。 return function() if ( table_name[key] == "end" ) then return nil,nil else local k = key key = key + 1 return k,func(table_name[k]) end end end do local my_lst = { "my", "name", "is", nil, "tattyu", "end", } -- 似たようなことをする関数を渡す. for i,v in my_pairs(my_lst,function(v)return (v and (v.." ") or "\n" )end) do io.write(v) end io.write("\n") end
結果
my name is tattyu