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

前端 未结 5 1535
执笔经年
执笔经年 2020-11-27 14:08

I\'ve just started learning Ruby and Ruby on Rails and came across validation code that uses ranges:

validates_inclusion_of :age, :in => 21..99
validates_         


        
相关标签:
5条回答
  • 2020-11-27 14:27

    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.

    0 讨论(0)
  • 2020-11-27 14:30

    .. and ... denote a range.

    Just see it in irb:

    ruby-1.9.2-p290 :032 > (1...2).each do puts "p" end
    p
     => 1...2 
    ruby-1.9.2-p290 :033 > (1..2).each do puts "p" end
    p
    p
    
    0 讨论(0)
  • 2020-11-27 14:39

    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"] 
    
    0 讨论(0)
  • 2020-11-27 14:46

    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

    0 讨论(0)
  • 2020-11-27 14:48

    a...b excludes the end value, while a..b includes the end value.

    When working with integers, a...b behaves as 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
    

    But really the ranges differ on a real number line.

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

    You can see this when incrementing in fractional steps.

    >> (-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]
    
    0 讨论(0)
提交回复
热议问题