|
2 | 2 |
|
3 | 3 | include Enumerable
|
4 | 4 |
|
5 |
| -範囲オブジェクトのクラス。範囲オブジェクトは範囲演算子 .. または |
6 |
| -... によって生成されます。.. 演算子によって生成された範囲 |
7 |
| -オブジェクトは終端を含み、... 演算子によって生成された範囲オブジェ |
8 |
| -クトは終端を含みません。 |
| 5 | +範囲オブジェクトのクラス。 |
| 6 | +範囲オブジェクトは文字どおり何らかの意味での範囲を表します。数の範囲はもちろん、 |
| 7 | +日付の範囲や、「"a" から "z" まで」といった文字列の範囲を表すこともできます。 |
9 | 8 |
|
10 |
| -=== 例 |
| 9 | +==== 作り方 |
11 | 10 |
|
12 |
| - for i in 1..5 |
13 |
| - # 処理 |
14 |
| - end |
| 11 | +範囲オブジェクトは、[[m:Range#new]] を用いるほか、範囲演算子(`..' または `...')を |
| 12 | +用いた [[ref:d:spec/operator#range]] で生成できます。 |
| 13 | +いずれの方法でも始端と終端を与えます。 |
| 14 | + |
| 15 | +#@samplecode 範囲オブジェクトの例 |
| 16 | +Range.new(1, 5) # 1 以上 5 以下 |
| 17 | +1..5 # 同上 |
| 18 | +1...5 # 1 以上 5 未満 |
| 19 | +#@end |
| 20 | + |
| 21 | +この例で分かるように、範囲オブジェクトは終端を含む範囲も含まない範囲も表せます。 |
| 22 | + |
| 23 | +#@since 2.6.0 |
| 24 | +Ruby 2.6.0 からは、終端に nil を与えることで「終端を持たない範囲オブジェクト」 |
| 25 | +を作ることができるようになりました。 |
| 26 | + |
| 27 | +#@samplecode 終端を持たない範囲オブジェクト |
| 28 | +p Range.new(1, nil) # 1 以上(上限無し)を表す |
| 29 | +p(1..nil) # 同上 |
| 30 | +p(1..) # 同上(略した書き方) |
| 31 | +#@end |
| 32 | + |
| 33 | +#@since 2.7.0 |
| 34 | +また、Ruby 2.7.0 では始端に nil を与えることで「始端を持たない範囲オブジェクト」 |
| 35 | +を作ることもできるようになりました。 |
| 36 | + |
| 37 | +#@samplecode 始端を持たない範囲オブジェクト |
| 38 | +p Range.new(nil, 5) # 5 以下(下限無し)を表す |
| 39 | +p(nil..5) # 同上 |
| 40 | +p(..5) # 同上(略した書き方) |
| 41 | +#@end |
| 42 | + |
| 43 | +始端も終端も持たない範囲オブジェクトは「全範囲」を表します。 |
| 44 | + |
| 45 | +#@samplecode 始端も終端も持たない範囲オブジェクト |
| 46 | +# 以下はすべて同じ範囲 |
| 47 | +p Range.new(nil, nil) # => nil..nil |
| 48 | +p(nil..nil) # => nil..nil |
| 49 | +p(..nil) # => nil..nil |
| 50 | +p(nil..) # => nil..nil |
| 51 | +#@end |
| 52 | + |
| 53 | +範囲式で両端を略した書き方はできません。 |
| 54 | + |
| 55 | + p(..) # => SyntaxError |
| 56 | + p(...) # Ruby 2.7 で導入されたメソッド引数の forward として解釈されてしまう |
| 57 | + |
| 58 | +#@end |
| 59 | +#@end |
| 60 | + |
| 61 | +==== 機能 |
| 62 | + |
| 63 | +範囲オブジェクトは範囲を表しているので、基本的な機能として「ある値がその範囲に |
| 64 | +含まれるか否かを判定する」ということがあります。 |
| 65 | + |
| 66 | +#@samplecode 値が範囲に含まれるかどうかを判定 |
| 67 | +p (1..5).cover?(6) # => false |
| 68 | +p (1..5).cover?(5) # => true |
| 69 | +p (1...5).cover?(5) # => false |
| 70 | +#@end |
| 71 | + |
| 72 | +[[m:Range#cover?]] メソッドでの判定には演算子 <=> が使われます。 |
| 73 | + |
| 74 | +当然、始端と終端は <=> メソッドで比較可能である(nil 以外を返す)必要が |
| 75 | +あります。 |
| 76 | + |
| 77 | +範囲オブジェクトのもう一つの基本的機能は繰り返しの範囲を表すことです。 |
| 78 | + |
| 79 | +#@samplecode 繰り返しの範囲を範囲オブジェクトで表す |
| 80 | +(3..5).each{ |i| p i } |
| 81 | +# => 3 |
| 82 | +# 4 |
| 83 | +# 5 |
| 84 | + |
| 85 | +(3...5).each{ |i| p i } |
| 86 | +# => 3 |
| 87 | +# 4 |
| 88 | +#@end |
15 | 89 |
|
16 |
| -これは 1 から 5 までの範囲オブジェクトを生成して、それぞれの値に対して |
17 |
| -繰り返すと言う意味です。 |
| 90 | +繰り返しの範囲を表す範囲オブジェクトは、始端が「次の値」を返す succ メソッドを |
| 91 | +持たなければなりません。 |
18 | 92 |
|
19 |
| -範囲演算子のオペランドは互いに <=> で比較できる必要があります。 |
20 |
| -さらに [[m:Range#each]] を実行するためには succ メソッ |
21 |
| -ドを実行できるものでなければいけません。 |
| 93 | +Range クラスには [[c:Enumerable]] が include してあるので,[[m:Range#each]] に |
| 94 | +基づき、Enumerable モジュールが提供する多様なメソッドを使うことができます。 |
22 | 95 |
|
23 | 96 | === 破壊的な変更
|
24 | 97 |
|
|
0 commit comments