Я только начал изучать 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..10).include? 10 #=> true
и(1...10).include? 10 #=> false
(a..b) != (a...(b+1))
несмотря на то, что их представления массива равны (когда a, b ∈ ℤ). Я немного обновил свой ответ, чтобы подробнее остановиться на этом.inject
происходит изEnumerable
которогоRange
включает;Enumerable
использует#each
, которыйRange
орудует . Список, созданный с помощьюRange#each
, никогда не содержится в самомRange
объекте.Это верно.
Синтаксис с тремя точками встречается реже, но он лучше, чем
(1..10-1).to_a
источник
..
более распространено, и поэтому для него предпочтительнее меньше?(a..b-1) != (a...b)
, хотя этот ответ подразумевает, что это так.Документы API теперь описывают это поведение:
Другими словами:
источник
a...b
исключает конечное значение, аa..b
включает конечное значение.При работе с целыми числами
a...b
ведет себя какa..b-1
.Но на самом деле диапазоны различаются на числовой прямой .
Вы можете увидеть это при дробном увеличении.
источник
a
&b
- целые числа, диапазоны разные. Только когда каждый из них преобразован в массив, они становятся одинаковыми. В принятом ответе есть конкретный контрпример... и ... обозначают диапазон.
Просто посмотрите это в irb:
источник