lua5.0の場合こういう記法のために標準で table.foreach というものが用意されていた。
第1引数に配列、第2引数に関数をとり、配列の要素ごとにその関数を呼ぶと言うもの。
関数には要素のインデックスと対応する値が渡される。
a = { 'a', 'b', 'c' } print( '--- table.foreach ---' ) table.foreach( a, function( index, item ) print( item, index ) end )
出力は
--- table.foreach --- a 1 b 2 c 3
5.1では廃止になったけどコンパイルオプションで組み込むことはできる。5.1ではforで同じことをするには ipairs を使う。
print( '--- for with ipairs ---' ) for index, item in ipairs( a ) do print( item, index ) end
http://d.hatena.ne.jp/amachang/20090119/1232331329 について
luaの場合localという命令で変数をつくることが出来る。スコープは出現位置からそのブロックのendまで。(2.6 - 可視ルール)
なのでクロージャーのために無名関数を使う必要は無いだけれど table.foreach は第2引数に関数を取るのでこうなる。
print( '--- c is closure local---' ) p = {} table.foreach( a, function( index, item ) local c = item p[ index ] = function() print( c ) end end ) p[1]() p[2]() p[3]()
local を無しのバージョン。
print( '--- c is global ---' ) p = {} table.foreach( a, function( index, item ) c = item p[ index ] = function() print( c ) end end ) p[1]() p[2]() p[3]()
出力は
--- c is closure local--- a b c --- c is global --- c c c
となる。
luaの場合でもfunction()で関数生成はそれなりにコストがかかのでfor-ipairsで以下のようにかくよりは table.foreach の方が軽い。
2009-01-21追記: 考えたら function()の生成コストではなく table.foreach()と for-ipairs の違いによるものである可能性があった。深追いはしないでおく。
p = {} for index, item in ipairs( a ) do (function( index, item ) local c = item p[ index ] = function() print( c ) end end)(index, item ) end p[1]() p[2]() p[3]()