BigBinary Blog

We write about Ruby on Rails, React.js, React Native, remote work, open source, engineering and design.

Ruby 2.7 adds Beginless Range

This blog is part of our Ruby 2.7 series.

Ruby 2.7.0 was released on Dec 25, 2019.

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.

1> array = (1..10).to_a
2
3# Select first 6 elements
4> array[..5]
5=> [1, 2, 3, 4, 5, 6]
6
7# Select first 5 elements
8> array[...5]
9=> [1, 2, 3, 4, 5]
10
11# grep (INFINITY..5) in (1..5)
12> (1..10).grep(..5)
13=> [1, 2, 3, 4, 5]
14
15# (..100) is equivalent to (nil..100)
16> (..100) == (nil..100)
17=> true

Here is another example where in the case statement the condition can be read as below the specified level.

1case temperature
2when ..-15
3  puts "Deep Freeze"
4when -15..8
5  puts "Refrigerator"
6when 8..15
7  puts "Cold"
8when 15..25
9  puts "Room Temperature"
10when (25..)   # Kindly notice the brackets here
11  puts "Hot"
12end

It can also be used for defining constants for ranges.

1TEMPERATURE = {
2  ..-15  => :deep_freeze,
3  -15..8 => :refrigerator,
4  8..15  => :cold,
5  15..25 => :room_temperature,
6  25..   => :hot
7end

Using Beginless Range in DSL makes it easier to write conditions and it looks more natural.

1
2# In Rails
3User.where(created_at: (..DateTime.now))
4# 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]]
5
6
7# In RubySpec
8ruby_version(..'1.9') do
9# Tests for old Ruby
10end

Here is the relevant commit and discussion regarding this change.

Ashwath Biradar in Ruby 2.7
August 25, 2020
Share

Subscribe to our newsletter