Разница между ".." (двойная точка) и "..." (тройная точка) в генерации диапазона?
Я только начал изучать Ruby и Ruby on Rails и наткнулся на код проверки, который использует диапазоны:
validates_inclusion_of :age, :in => 21..99
validates_exclusion_of :age, :in => 0...21, :message => "Sorry, you must be over 21"
Сначала мне показалось, что разница заключалась в включении конечных точек, но в документах API, которые я просмотрел, не казалось, что это было ..
или ...
: он всегда включал конечные точки.
Тем не менее, я провел некоторое тестирование в irb, и это показало, что ..
включает обе конечные точки, а ...
включает только нижнюю границу, но не верхнюю. Правильно ли это?
Ответы
Ответ 1
Документация для диапазона † говорит следующее:
Диапазоны, построенные с использованием ..
, выполняются от начала до конца включительно. Те, которые созданы с использованием ...
, исключают конечное значение.
Итак, a..b
похож на a <= x <= b
, тогда как a...b
похож на a <= x < b
.
Обратите внимание, что, хотя to_a
в диапазоне целых чисел дает набор целых чисел, диапазон не является набором значений, а просто пара начальных/конечных значений:
(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
† Документы, используемые, чтобы не включать это, вместо этого требуя прочитать раздел см. Ниже) для уведомления об этом обновлении.
Ответ 2
Это правильно.
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]
Синтаксис с тремя точками менее распространен, но лучше, чем (1..10-1).to_a
Ответ 3
В документах API теперь описывается это поведение:
Диапазоны, построенные с использованием ..
, выполняются от начала до конца включительно. Те, которые созданы с использованием ...
, исключают конечное значение.
- http://ruby-doc.org/core-2.1.3/Range.html
Другими словами:
2.1.3 :001 > ('a'...'d').to_a
=> ["a", "b", "c"]
2.1.3 :002 > ('a'..'d').to_a
=> ["a", "b", "c", "d"]
Ответ 4
a...b
исключает конечное значение, тогда как a..b
включает конечное значение.
При работе с целыми числами a...b
ведет себя как 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
Но действительно диапазоны отличаются на номер реального номера.
>> (-1..2) == (-1...3)
=> false
Вы можете видеть это, когда увеличиваете дробные шаги.
>> (-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]
Ответ 5
.. и... обозначают диапазон.
Просто просмотрите его в 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