index(Object.[x])やslice(Object.[x y])について
配列(Array)や連想配列(Map)や文字列(String)を扱うための構文糖(シンタクスシュガー)、[]構文の解説です。
角括弧内の引数の数が1つならindex、2つならsliceとなり、それに加え、角括弧に=が付くと*_setとなります。
s: 'abcedfg' s.[0] //s.index(0) s.[0 1] //s.slice(0 1) s.[1] = \A //s.index_set(1 \A) s.[1 2] = (\A \B) //s.slice_set(1 2 \A \B)
index
数値が負数の場合、"要素数 + 負数"となります。その結果も負数の場合は、要素数より値が大きい場合と同じくエラーになります。
'abcedfg'.[0] //\a 'abcedfg'.[1] //\b {10 20 30}.[2] //30 Map.new(\a.=> 1 \b.=> 2 \c.=> 3).[\b] //2 'abcedfg'.[-1] //\g {10 20 30}.[3] //エラー
連想配列に対して存在しないキーを指定した場合は、そのキーが作成され、初期値であるNULLオブジェクトが返ります。
Map.new(\a.=> 1 \b.=> 2 \c.=> 3).[\d] //NULL (アクセスすると強制終了)
index_set
indexメソッドの戻り値に対し、内部的に、直接、代入演算子を発動します。ArrayやMapの値の初期値はNULLオブジェクトであるため、indexの戻り値の代入演算子の呼び出しは不可能であり、index_setが必要になります。
s:: 'abcedfg' //s: 'abcdefg'.copy s.[0] = \A //s.[0].= \A と結果は同じだが、index_setのほうが直接的であるため速い s.== 'Abcdefg' a: {10 20 30} a.resize(4) a.[3] = 40 //a.[3].= 40 ではa.[3]の戻り値であるNULLオブジェクトの=メソッドを呼び出そうとするため強制終了することになる a.== {10 20 30 40} m: Map.new(\a.=> 1 \b.=> 2 \c.=> 3) m.[\d] = 4 //m.[\d].= 4 ではm.[\d]の戻り値であるNULLオブジェクトの=メソッドを呼び出そうとするため強制終了することになる m.[\d].== 4
slice
引数は、[position count]となります。戻り値は、positionからcount数の値を有したselfと同じ型のオブジェクトです。値が負数の場合はindexと同じ扱いです。数値が過大な場合は、要素数扱いとなります。連想配列(Map)には使用できません。
'abcdefg'.[2 3] //'cde' 'abcdefg'.[2 -1] //'cdef' 'abcdefg'.[-5 3] //'cde' 'abcdefg'.[10 3] //'' 'abcdefg'.[1 Uint.max_limit] //'bcdefg'
slice_set
指定された部分をself.eraseで消し、その位置に代入演算子右辺の値をself.insertで挿入します。右辺には複数の値を置けます。右辺に配列等を置いても、数値等を置いた場合と動作が変わることはありません。
s:: 'abcdefg' s.[2 3] = \- s.== 'ab-fg' s:: 'abcdefg' s.[2 3] = 'ABCDEFG' //String.insertは文字列を受け取れる s.== 'abABCDEFGfg' s:: 'abcdefg' s.[2 3] = (\- \= \-) //複数の右辺引数 s.== 'ab-=-fg' s:: 'abcdefg' s.[2 3] = () //右辺引数がゼロならinsertは呼ばれず、Rubyのslice!と同じ結果になる s.== 'abfg'