August 25, 2020
This blog is part of our Ruby 2.7 series.
Ruby 2.7 added support for Beginless Range which makes the start of range an optional parameter.
(..100)
is a Beginless Range and it is equivalent to (nil..100)
.
Let's see how Beginless Range could be used.
> array = (1..10).to_a
# Select first 6 elements
> array[..5]
=> [1, 2, 3, 4, 5, 6]
# Select first 5 elements
> array[...5]
=> [1, 2, 3, 4, 5]
# grep (INFINITY..5) in (1..5)
> (1..10).grep(..5)
=> [1, 2, 3, 4, 5]
# (..100) is equivalent to (nil..100)
> (..100) == (nil..100)
=> true
Here is another example where in the case
statement the condition can be read
as below the specified level
.
case temperature
when ..-15
puts "Deep Freeze"
when -15..8
puts "Refrigerator"
when 8..15
puts "Cold"
when 15..25
puts "Room Temperature"
when (25..) # Kindly notice the brackets here
puts "Hot"
end
It can also be used for defining constants for ranges.
TEMPERATURE = {
..-15 => :deep_freeze,
-15..8 => :refrigerator,
8..15 => :cold,
15..25 => :room_temperature,
25.. => :hot
end
Using Beginless Range in DSL makes it easier to write conditions and it looks more natural.
# In Rails
User.where(created_at: (..DateTime.now))
# User Load (2.2ms) SELECT "users".* FROM "users" WHERE "users"."created_at" <= $1 LIMIT $2 [["created_at", "2020-08-05 15:00:19.111217"], ["LIMIT", 11]]
# In RubySpec
ruby_version(..'1.9') do
# Tests for old Ruby
end
Here is the relevant commit and discussion regarding this change.
If this blog was helpful, check out our full blog archive.