Ruby’s New Infinite Range Syntax: (0..)
This Christmas, Ruby 2.6 will be released with support for a new syntax denoting an infinite range!
Introducing Ruby 2.6’s Endless Range
On Christmas Day, 2018, Ruby 2.6 will be released with support for a new syntax denoting an endless range:
42..
#=> 42..nil # yes, this is infinite!
So why do we need this new syntax? Up to this point, it has been a bit clunky in Ruby to create an infinite range:
42..Float::INFINITY
#=> 42..Infinity
Nobody likes typing Float::INFINITY
or 1.fdiv(0)
over and over. It doesn’t seem like a nice solution to put forward as the idiomatic way in Ruby. However, some Rubyists argued that we didn’t need an infinite range because Integer#step
already lets you iterate from n
to infinity:
42.step
#<Enumerator: ...>
42.step.size
#=> Infinity
In the end, Matz (the creator of Ruby) made the decision to accept the endless range syntax proposal, saying, “I honestly feel there should be a fluent way to do 0..Float::INFINITY
.”
Usage Examples
What can we do with this new syntax? One useful thing we can do is access elements until the last element in the series:
[:a, :b, :c, :d, :e][2..]
#=> [:c, :d, :e]
'012345'[2..]
#=> "2345"
In previous version of Ruby, we would have used -1
to denote that we want all elements up to the last element:
[:a, :b, :c, :d, :e][2..-1]
#=> [:c, :d, :e]
'012345'[2..-1]
#=> "2345"
Ranges also respond to threequals, so we can now do neat things with case statements:
case 2022
when(2030..)
:mysterious_future
when(2020..)
:twenties
when(2010..)
:nowish
else
:ancient_past
end
#=> :twenties
Another use for the new ranges is to use them with #zip
to approximate a combination of #each
, #with_index
and #to_a
:
[:a, :b, :c].zip(42..)
#=> [[:a, 42], [:b, 43], [:c, 44]
# instead of:
[:a, :b, :c].each.with_index(42).to_a
#=> [[:a, 42], [:b, 43], [:c, 44]]
Or two infinite ranges can even be zipped together lazily:
(:a..).lazy.zip(42..).first(3)
#=> [[:a, 42], [:b, 43], [:c, 44]]
Finally, one of the most useful things to do with an infinite range is to iterate infinitely:
(42..).each { |n| # forever! }
Conclusion
The new infinite range syntax is due to be released with Ruby 2.6 on December 25, 2018. If you’d like to play with it before then, try the nightly Ruby snapshot. Or it will be included in the upcoming release of ruby-2.6.0-preview2. We have Yusuke Endoh to thank for this new syntax, as he both proposed and implemented the feature.
We use Ruby for lots of things here at Square — including in our Square Connect Ruby SDKs and our open source Ruby projects. We’re eagerly awaiting the release of Ruby 2.6!
Want more? Sign up for your monthly developer newsletter or drop by our dev Slack channel and say “hi!”