I've just started learning Ruby and Ruby on Rails and came across validation code that uses ranges:
我刚刚开始学习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"
At first I thought the difference was in the inclusion of endpoints, but in the API docs I looked into, it didn't seem to matter whether it was ..
or ...
: it always included the endpoints.
一开始我认为差异在于包含端点,但在我研究的API文档中,是否包含端点似乎并不重要。还是……:它总是包含端点。
However, I did some testing in irb and it seemed to indicate that ..
includes both endpoints, while ...
only included the lower bound but not the upper one. Is this correct?
然而,我在irb做了一些测试,似乎表明…包含两个端点,而…只包括下界,不包括上界。这是正确的吗?
5 个解决方案
#1
117
The documentation for Range† says this:
Range的文档说
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
.
所以. .b就像a <= x <= b,而a…b就像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:
注意,虽然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
†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.
以前的文档中不包含这个,而是需要阅读《鹤嘴锄》中关于范围的章节。感谢@MarkAmery(见下文)注意到这次更新。
#2
4
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
三点语法不太常见,但比(1..10 .1).to_a要好
#3
3
The API docs now describe this behaviour:
API文档现在描述了这种行为:
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
——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"]
#4
1
a...b
excludes the end value, while a..b
includes the end value.
一个……b不包含结束值,a。b包含最终值。
When working with integers, a...b
behaves as a..b-1
.
当使用整数时,a…b . . 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]
#5
-4
.. and ... denote a range.
. .和…表示一个范围。
Just see it in irb:
看看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
#1
117
The documentation for Range† says this:
Range的文档说
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
.
所以. .b就像a <= x <= b,而a…b就像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:
注意,虽然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
†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.
以前的文档中不包含这个,而是需要阅读《鹤嘴锄》中关于范围的章节。感谢@MarkAmery(见下文)注意到这次更新。
#2
4
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
三点语法不太常见,但比(1..10 .1).to_a要好
#3
3
The API docs now describe this behaviour:
API文档现在描述了这种行为:
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
——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"]
#4
1
a...b
excludes the end value, while a..b
includes the end value.
一个……b不包含结束值,a。b包含最终值。
When working with integers, a...b
behaves as a..b-1
.
当使用整数时,a…b . . 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]
#5
-4
.. and ... denote a range.
. .和…表示一个范围。
Just see it in irb:
看看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