読者です 読者をやめる 読者になる 読者になる

コモディティ化するエンジニア

組み込み系のSI屋から、Railsを扱うWeb系のベンチャーに転職した筆者が、日々ミジンコなりに情報を綴るブログ。

Ruby Koans をやってみた( 1 〜 23 ):Rubyでの配列領域外アクセス

Ruby Koansとは?!

既にテストシナリオ(?)と結果が書かれているので、以下のようなコードにおいて、
__ に埋まる期待値を書きなさい。というもの。

  array = [:peanut, :butter, :and, :jelly]
  assert_equal __, array[0,1]

Ruby文法の理解度確認と、テスト駆動開発の体験を同時に満たすことができます。
全部で282も問題があるため、ボリューム満点です。

公式サイト(配布元) Learn Ruby with the Neo Ruby Koans

同梱の README.rdoc を読めば、始め方はわかるようになっているのですが、 私のように「日本語でお願いします……」という方は、こちらの記事が導入の参考になります。

questbeat.hatenablog.jp

今回の疑問点

Ruby Koans の about_arrays.rb 中、以下の問題があります。
とある配列に対して、様々なアクセスを試してみて、どんな値が返ってくるでしょうか?
というものです。

def test_slicing_arrays
  array = [:peanut, :butter, :and, :jelly]

  assert_equal __, array[0,1]
  assert_equal __, array[0,2]
  assert_equal __, array[2,2]
  assert_equal __, array[2,20]
  assert_equal __, array[4,0]
  assert_equal __, array[4,100]
  assert_equal __, array[5,0]
end

答えは、

def test_slicing_arrays
  array = [:peanut, :butter, :and, :jelly]

  assert_equal [:peanut], array[0,1]
  assert_equal [:peanut, :butter], array[0,2]
  assert_equal [:and, :jelly], array[2,2]
  assert_equal [:and, :jelly], array[2,20]
  assert_equal [], array[4,0]
  assert_equal [], array[4,100]
  assert_equal nil, array[5,0]
end

になるのですが……初見では後半3問が解せませんでした。
なぜ、領域外を参照すると、空になったりnilになったりするのでしょうか?
Arrayクラスのリファレンスで self[range] -> Array | nil の項を引いてみると、

a = [ "a", "b", "c", "d", "e" ]

# 特殊なケース。first が自身の長さと同じ場合には以下のようになります。
a[5]                   #=> nil
a[5, 1]                #=> []
a[5..10]               #=> []

と記載されています。
うーん……"特殊なケース" の一言で片付けられても……
Cみたいに不定値(配列外領域の番地の値)が入っているなら納得できるんですが。

これ以上詳しい解説を、現状の自分では見つけられなかったので、
この件については以上。初回から投げっぱなしですみません。