👻
[Feature #20080] Introduce #bounds method on Range
[Feature #20080] Introduce #bounds method on Range
-
Range#begin, endを返すRange#boundsメソッドを追加する提案
# [begin, end] の配列を返す
first, last = (1..300).bounds # => [1, 300]
first, last = (300..1).bounds # => [300, 1]
first, last = (..300).bounds # => [nil, 300]
first, last = (1..).bounds # => [1, nil]
- また
Range#exclude_end?がtrueの場合はその情報が第三要素で受け取る事ができる- これを利用してシリアライズ化が簡単にできるようになる
# ... の場合は第三要素に true が渡される
a = (1..2).bounds #=> [1,2]
b = (1...2).bounds #=> [1,2,true]
# これを利用すると bounds の結果から元の Range を簡単に復元する事ができる
Range.new(*a) #=> 1..2
Range.new(*b) #=> 1...2
- この
Range#exclude_end?値を含めるか含めないかはRange#boundsの引数で制御することができる
# true を渡すと Range#exclude_end? の結果に変わらずに含める
(1..2).bounds(true) #=> [1,2,false]
(1...2).bounds(true) #=> [1,2,true]
# false を渡すと Range#exclude_end? の結果に変わらずに含めない
(1..2).bounds(false) #=> [1,2]
(1...2).bounds(false) #=> [1,2]
- このチケットの背景は Feature #20027: Add Range Deconstruction で
Rangeを分割代入したい、っていう要望からの派生ですね - 上記のチケットだと
Rangeを直接分割代入するのは Reject されたんですが、その代わりにメソッドを追加する案があったのでそれの派生になります -
Range#minmaxと似ているんですが#minmaxの場合はbegin > endの場合にnilを返したりするのでちょっとだけ挙動が異なります
(1..42).minmax #=> [1, 42]
(42..1).minmax #=> [nil, nil]
- まあ普通に便利そうな感じはしますねー
Discussion