Ruby Literals You May Not Know

- ruby

In programming the term “literal” refers to notations for representing certain values in code. Almost all languages offer them for atomic types such as strings or various number formats, some also for compound types like arrays, records or hashes. Additionally lambda expressions are a literal representation of functions.

Ruby has a rich set of literals for various use cases and in this post we’re going to explore some of the lesser known ones.

Rational

The Rational class represents irreducible fractions. These can be created via Kernel#Rational, various to_r implementations, but also the r suffix on other numeric literals:

3/5r
#=> (3/5)

(3/5r).class
#=> Rational

2/4r
#=> (1/2)

2/3r + 3/4r
#=> (17/12)

Rationals represent exact numbers, so we don’t have to worry about rounding errors:

10.times.inject(0) { |t| t + 0.1 }.to_i
#=> 0

10.times.inject(0) { |t| t + 1/10r }.to_i
#=> 1

Complex

In a similar vain Ruby also has support for complex numbers consisting of a real and imaginary part. These can not only be constructed via Kernel#Complex or to_c, but also via a literal notation:

1i
#=> (0+1i)

1+0i
#=> (1+0i)

0.9-1.3i
#=> (0.9-1.3i)

Admittedly this is not a number type Ruby programmers will frequently need, but it does come in handy when dealing with electronics, wave functions, or similar topics.

String Percent Literals

In addition to single and double quotes, Ruby has several other options for creating strings. %Q (or just %) behaves like a double quoted string and %q like a single quoted one. The delimiters can be chose relatively freely. This is for example useful if we don’t want to deal with escaping quotes:

%(He said "Hello")
#=> "He said \"Hello\""

%Q(He said "Hello")
#=> "He said \"Hello\""

%q(It's time to go)
=> "It's time to go"

%(#{1 + 1})
#=> "2"

%q(#{1 + 1})
#=> "\#{1 + 1}"

Character

While Ruby doesn’t have a dedicated character class, it does have a ? prefixed literal for creating single character strings. This doesn’t only work for ASCII characters, but also escape sequences and unicode characters/symbols:

?a
#=> "a"

?\n
#=> "\n"

?\C-a
#=> "\u0001"

?ค
#=> "ค"

?我
#=> "我"

Endless Ranges

Since Ruby 2.6 there’s a new range literal that allows for open-ended ranges:

(1..)
#=> 1..

This is especially useful in combination with the various Enumerable methods:

odd_numbers = (0..).lazy.map { |n| n * 2 + 1}
odd_numbers.first(5).sum
#=> 25

Regular Expressions

Apart from the normal /.../ regular expressions literals, Ruby also has an alternative %r notation. This is useful when matching strings with multiple forward slashes, for example path names:

path = "/home/user/many/more/folders/"

path.match?(/\/home\/user\/many/)
#=> true

path.match?(%r{/home/user/many})
#=> true

Apart from escaping they behave exactly like the other literal form and allow for interpolation and modifiers:

user = "user"
path.match?(%r{/home/#{user}/many})
#=> true

"TEST".match?(%r[test]i)
#=> true

Summary

Ruby has many and convenient and useful literals, which are well documented. While some of the literals shown in this post are certainly more obscure than their more well-know counterparts, they do come in handy in specific circumstances, e.g. when trying to avoid escaping.

Comments powered by Talkyard.