From: matz@... (Yukihiro Matsumoto) Date: 1998-10-30T17:37:32+09:00 Subject: [ruby-list:10507] Re: negative index of an array まつもと ゆきひろです In message "[ruby-list:10454] Re: negative index of an array" on 98/10/29, Motoyuki Kasahara writes: |笠原です。こんにちは。 |> * start or endが負の時には「配列の長さ+(start or end)」と |> みなします |> |> * さらに「配列の長さ+(start or end)」がまだ負の時には0とみ |> なします. | |なるほど、こうなっているのですね。(同様に小田さんも 0 とみなされるとい |うことは書かれていました。) しかし,この機会に良く考えてみると「まだ負だったら0にする」 というのは以下にも乱暴です.考え直した方が良いように思えてき ました. |ただ、個人的には、 | | a = ['a', 'b', 'c'] | a[-6..-5] = ['X', 'Y'] # a => ['X', 'Y', nil, 'a', 'b', 'c'] | |という結果になると、代入直後は a[-6..-5] が ['X'、'Y'] になるので、もっ |とも自然だと思えるのですが、どうでしょう。 なるほど,後方だけでなく前方にも自動拡張するわけですね. 私が考えていたのは,参照については a = [1,2,3] a[-4] #=> 配列外なのでnil(現状は1) a[-4,0] #=> 配列外なので[](現状も[]) a[-4,1] #=> 配列外なので[](現状は[1]) a[-4,2] #=> 配列外を除く[1](現状は[1,2]) a[-4..-4] #=> 配列外なので[](現状も[]) a[-4..0] #=> 配列外を除く[1](現状も[1]) で,代入については, * 前方の配列外への代入は例外 * (負の位置からスタートする)範囲指定で配列に重なる部分があ れば,そこだけを置き換える というのはどうだろうか,というものです. 前方への自動拡張は考えていませんでしたが,どうなんでしょう. 勝手にシフトするのは良くないというような気がしないでもないで すが…. |> * さらに「配列の長さ+(start or end)」がまだ負の時には0とみ |> なします. | |このルールはインデックスとして引数に srart..end や start, length をと |るメソッドに限って採用されているのですよね? delete_at(index) や |self[nth] といったメソッドでは、このルールは適当されないようです。とく |に `self[nth] = value' メソッドは例外が発生します。例外が発生するのは |このメソッドだけのようです。 この辺も一貫性がないので揃えるようにしましょう. |ところで、引数 start, length の length が負のときは、常に例外が発生す |ると思っていたのですが、start の値によって挙動が変わります。 | | a = [0, 1, 2] | a[0, -2] = ['a', 'b'] # 例外: negative length 3 (IndexError) | | a = [0, 1, 2] | a[4, -2] = ['a', 'b'] # a => [0, 1, 2, nil, 'a', 'b'] | |これは何故なのでしょうか。 ミスフィーチャというかほとんどバグですね.長さチェックより配 列拡張のチェックが先に来てたせいです.負の長さはいつも例外に するようにしましょう. いずれにしてもこれへの対応は1.1dで行います. まつもと ゆきひろ /:|)