Difference between '..' (double-dot) and '...' (triple-dot) in range generation? Difference between '..' (double-dot) and '...' (triple-dot) in range generation? ruby ruby

Difference between '..' (double-dot) and '...' (triple-dot) in range generation?


The documentation for Range says this:

Ranges constructed using .. run from the beginning to the end inclusively. Those created using ... exclude the end value.

So a..b is like a <= x <= b, whereas a...b is like a <= x < b.


Note that, while to_a on a Range of integers gives a collection of integers, a Range is not a set of values, but simply a pair of start/end values:

(1..5).include?(5)           #=> true(1...5).include?(5)          #=> false(1..4).include?(4.1)         #=> false(1...5).include?(4.1)        #=> true(1..4).to_a == (1...5).to_a  #=> true(1..4) == (1...5)            #=> false


The docs used to not include this, instead requiring reading the Pickaxe’s section on Ranges. Thanks to @MarkAmery (see below) for noting this update.


That is correct.

1.9.3p0 :005 > (1...10).to_a => [1, 2, 3, 4, 5, 6, 7, 8, 9]1.9.3p0 :006 > (1..10).to_a => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

The triple-dot syntax is less common, but is nicer than (1..10-1).to_a


The API docs now describe this behaviour:

Ranges constructed using .. run from the beginning to the end inclusively. Those created using ... exclude the end value.

-- http://ruby-doc.org/core-2.1.3/Range.html

In other words:

2.1.3 :001 > ('a'...'d').to_a => ["a", "b", "c"] 2.1.3 :002 > ('a'..'d').to_a => ["a", "b", "c", "d"]