範圍型態


如果使用begin..end或begin...end,這會建立Range實例,代表指定的範圍,begin..end表示包括end,begin...end表示不包括end。例如:
>> 1..5
=> 1..5
>> (1..5).class
=> Range
>> (1..5).each { |i| puts i}
1
2
3
4
5
=> 1..5
>> (1...5).each { |i| puts i }
1
2
3
4
=> 1...5
>>


可以使用begin方法得知範圍起點,使用end方法得知範圍指定終點,使用exclude_end?得知範圍是否排除終點。例如:
>> r = 1..5
=> 1..5
>> r.begin
=> 1
>> r.end
=> 5
>> r.exclude_end?
=> false
>> r = 1...5
=> 1...5
>> r.begin
=> 1
>> r.end
=> 5
>> r.exclude_end?
=> true
>>


範圍不僅可以是整數,也可以是字元或浮點數,只不過浮點數的範圍無法進行迭代。例如:
>> ("a".."g").each { |c| puts c }
a
b
c
d
e
f
g
=> "a".."g"
>> (1.0..3.0).each { |c| puts c }
TypeError: can't iterate from Float
        from (irb):79:in `each'
        from (irb):79
        from C:/Winware/Ruby192/bin/irb:12:in `<main>'
>>


可以使用include?方法得知範圍物件是否包括某個整數、浮點數或字元。例如:
>> (1.0..3.0).cover? 2.1
=> true
>> (1..10).include? 3
=> true
>> (1..10).include? 0
=> false
>> (1.0..3.0).include? 2.1
=> true
>> (1.0..3.0).include? 3.1
=> false
>> ("a".."g").include? "e"
=> true
>> ("a".."g").include? "x"
=> false
>>


也可以使用cover?測試物件是否在指定的begin與end之間。例如:
>> (1..10).cover? 3
=> true
>> (1.0..10.0).cover? 3.0
=> true
>> ("a".."m").cover? "x"
=> false
>> ("a".."m").cover? "d"
=> true
>> ("a".."m").cover? "abcd"
=> true
>> ("a".."m").cover? "xyz"
=> false
>>


注意,在(begin..end).cover? var時,為測試是否var>=begin且var<=end(如果是begin...end,則是var<end),所以("a".."m").cover? "abcd"時,是測試"abcd">="a"且"abcd"<="m"。

在介紹
字串型態陣列型態 時,談到[n..m]與[n...m]的索引方式,事實上,[]中的n..m與n...m建立了Range實例。例如:
>> r = 2..5
=> 2..5
>> [1, 2, 3, 4, 5, 6, 7][r]
=> [3, 4, 5, 6]
>> "This is a test"[r]
=> "is i"
>>


建立Range時,end可以小於begin,不過無法迭代:
>> r = 3..-1
=> 3..-1
>> r.each { |i| puts i }
=> 3..-1
>> r.include? 2
=> false
>> r.cover? 2
=> false
>>


建立Range時,end小於begin,通常為應用於字串與陣列的特例。例如:
>> r = 3..-1
=> 3..-1
>> [1, 2, 3, 4, 5, 6, 7][r]
=> [4, 5, 6, 7]
>> "This is a test"[r]
=> "s is a test"
>>


可以使用to_a將範圍轉為陣列,不過浮點數範圍不適用,範圍的end小於begin時,會得到空陣列。例如:
>> (1..10).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> ("a".."c").to_a
=> ["a", "b", "c"]
>> (1.0..3.0).to_a

TypeError: can't iterate from Float
        from (irb):14:in `each'
        from (irb):14:in `to_a'
        from (irb):14
        from C:/Winware/Ruby192/bin/irb:12:in `<main>'
>> (10..9).to_a
=> []
>>