web-dev-qa-db-fra.com

Différence entre '..' (double point) et '...' (triple point) dans la génération de plage?

Je viens juste de commencer à apprendre Ruby et Ruby sur Rails et j'ai trouvé le code de validation qui utilise des plages:

validates_inclusion_of :age, :in => 21..99
validates_exclusion_of :age, :in => 0...21, :message => "Sorry, you must be over 21"

Au début, je pensais que la différence résidait dans l'inclusion de points de terminaison, mais dans les documents sur l'API que j'ai examinés, peu importait qu'il s'agisse de .. ou ...: il a toujours inclus les points de terminaison.

Cependant, j’ai fait quelques tests dans irb et cela a semblé indiquer que .. inclut les deux extrémités, tandis que ... n'inclut que la limite inférieure mais pas la limite supérieure. Est-ce correct?

96
juil

Le documentation pour Range dit ceci:

Plages construites avec .. courir du début à la fin inclusivement. Ceux créés avec ... exclut la valeur finale.

Alors a..b est comme a <= x <= b, tandis que a...b est comme a <= x < b.


Notez que, alors que to_a sur une plage d’entiers donne une collection d’entiers, une plage est pas un ensemble de valeurs, mais simplement une paire de valeurs de début/fin:

(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


Auparavant, la documentation ne l’incluait pas, mais nécessitait la lecture du section de Pickaxe sur les plages . Merci à @MarkAmery ( voir ci-dessous ) pour avoir pris note de cette mise à jour.

144
Andrew Marshall

C'est 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]

La syntaxe à trois points est moins courante, mais plus agréable que (1..10-1).to_a

5
Chris Heald

La documentation de l'API décrit maintenant ce comportement:

Plages construites avec .. courir du début à la fin inclusivement. Ceux créés avec ... exclut la valeur finale.

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

En d'autres termes:

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

a...b exclut la valeur finale alors que a..b inclut la valeur finale.

Lorsque vous travaillez avec des entiers, a...b se comporte comme a..b-1.

>> (-1...3).to_a
=> [-1, 0, 1, 2]

>> (-1..2).to_a
=> [-1, 0, 1, 2]

>> (-1..2).to_a == (-1...3).to_a
=> true

Mais en réalité, les plages diffèrent sur un ligne de nombres réels .

>> (-1..2) == (-1...3)
=> false

Vous pouvez le voir en incrémentant par étapes.

>> (-1..2).step(0.5).to_a
=> [-1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0]

>> (-1...3).step(0.5).to_a
=> [-1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5]
1
Dennis