index(Object.[x])やslice(Object.[x y])について

これは古い情報です。この件に関する新しい情報はindex(Object.[x])やslice(Object.[x y])について - Giraffe+の開発についてのブログです。(2007-10-29追記)
配列(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

そのオブジェクトの内部にあるインスタンスのoperator[]を呼び出します。配列や文字列に対して存在しないエレメント(サイズ以上もしくは0未満のインデクス指定)をした場合はほぼ間違いなく強制終了することになります。(将来、安全な仕様に変わるかもしれません。)連想配列に対して同じような行為(存在しないキーの指定)を行った場合は、そのキーが作成され、初期値であるNULLオブジェクトが返ります。

'abcedfg'.[0] //\a
'abcedfg'.[1] //\b
{10 20 30}.[2] //30
Map.new(\a.=> 1 \b.=> 2 \c.=> 3).[\b] //2

'abcedfg'.[-1] //強制終了
{10 20 30}.[3] //強制終了
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

引数は、[pos count]となります。戻り値は、posまでeraseして、countにresizeしたselfのコピーです。countに不正な数値(サイズ以上もしくは0未満のインデクス指定)を置いた場合、resizeされません。posが不正な場合、-1以下なら、0扱い、サイズ以上ならサイズ扱い(clearされる)となります。連想配列(Map)には使用できません。(将来、対応するかもしれません。)

'abcdefg'.[2 3] //'cde'
'abcdefg'.[2 -1] //'cdefg'
'abcdefg'.[-1 3] //'abc'
'abcdefg'.[10 3] //''

slice!

Rubyと違い、selfをsliceの戻り値にします。(同じようにするには、slice_setを使います。)

s:: 'abcdefg'
s.[2 3]!
s.== 'cde'

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'