範囲¶
範囲は、2つの値の間の区間を表します。 通常、2つまたは3つのドットで構成される範囲リテラルを使用して構築されます。
x..y
:2つのドットは、x
とy
、およびその間のすべての値を含む、包含的範囲を示します(数学では[x, y]
)。x...y
:3つのドットは、x
と、y
を含まないまでのすべての値を含む、排他的範囲を示します(数学では[x, y)
)。
(0..5).to_a # => [0, 1, 2, 3, 4, 5]
(0...5).to_a # => [0, 1, 2, 3, 4]
注記
範囲リテラルは、たとえば、呼び出しのレシーバーとして使用される場合、括弧で囲まれることがよくあります。 括弧のない0..5.to_a
は、メソッド呼び出しや他の演算子は範囲リテラルよりも優先順位が高いため、セマンティック的には0..(5.to_a)
と同等です。
どちらが包含的でどちらが排他的であるかを覚える簡単な方法は、余分なドットがまるで*y*をさらに遠くに押しやって、範囲外に置いておくかのように考えることです。
リテラルx..y
は、明示的なコンストラクタ`Range.new(x, y)`とセマンティック的に同等であり、`x...y`は`Range.new(x, y, true)`と同等です。
開始値と終了値は必ずしも同じ型である必要はありません。 `true..1`は有効な範囲ですが、`Enumerable`メソッドは互換性のない型では機能しないため、あまり役に立ちません。少なくとも比較可能である必要があります。
nil
で始まる範囲は開始のない範囲と呼ばれ、nil
で終わる範囲は終了のない範囲と呼ばれます。 リテラル表記では、`nil`を省略できます。 `x..`は`x`から始まる終了のない範囲であり、`..x`は`x`で終わる開始のない範囲です。
numbers = [1, 10, 3, 4, 5, 8]
numbers.select(6..) # => [10, 8]
numbers.select(..6) # => [1, 3, 4, 5]
numbers[2..] = [3, 4, 5, 8]
numbers[..2] = [1, 10, 3]
開始と終了のない範囲は有効であり、`..`または`...`と表現できますが、通常はあまり役に立ちません。