Ruby’s New Infinite Range Syntax: (0..)

Shannon Skipper
Apr 20, 2018 · 2 min read

Heads up, we’ve moved! If you’d like to continue keeping up with the latest technical content from Square please visit us at our new home https://developer.squareup.com/blog

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!”

Square Corner Blog

Buying and selling sound like simple things - and they…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store