Strings and symbols

Ruby · Essentials · 10 min

Text processing is everywhere, and Ruby's string API plus symbols are used in every Ruby program.

Double-quoted strings interpolate with #{} and process escapes: "Hi #{name}\n". Single-quoted strings are literal. Heredocs build multi-line text, and the squiggly form <<~TEXT strips the common leading indentation.

The String API is large and readable: upcase, capitalize, strip, split, include?, start_with?, sub/gsub (with strings or regexes), center, ljust, * for repetition, and [] with an index, range or regex. format("%.2f", x) and "%05d" % n format numbers.

Ruby strings are mutable. << appends in place, and bang methods like upcase! modify the receiver (returning nil if nothing changed). Non-bang methods return a new string. Two variables can share one string object, so in-place changes are visible through both.

Adding # frozen_string_literal: true at the top of a file makes all literals frozen (immutable). In Ruby 3.4, literals in files without the comment are "chilled": mutating them still works but emits a deprecation warning when deprecation warnings are enabled, as a step toward frozen literals by default. Use +"" or String.new when you need a mutable buffer.

A Symbol like :status is an immutable name; the same symbol is always the same object. Use symbols for identifiers and hash keys, strings for text data. str.to_sym and sym.to_s convert between them.

Example

# frozen_string_literal: true
name = "Ruby"
puts "Hi #{name}, #{name.length} chars"   # Hi Ruby, 4 chars
puts 'No #{interp} here'                  # No #{interp} here

text = <<~MSG
  Dear #{name},
    indented line
MSG
puts text                                 # leading indentation removed

puts "a,b,,c".split(",").inspect          # ["a", "b", "", "c"]
puts "hello world".gsub(/o/, "0")         # hell0 w0rld
puts format("%.2f|%5s|", 3.14159, "x")    # 3.14|    x|

buf = +""            # mutable even with frozen literals
buf << "a" << "b"
puts buf             # ab
puts "lit".frozen?   # true (magic comment)
puts :ok.equal?(:ok) # true: one object per symbol

Remember

  • Use "#{}" for interpolation and <<~ for indented heredocs
  • Bang methods and << mutate; most other methods return new strings
  • Symbols are immutable identifiers; strings are text data

Watch out for

  • Modifying a string that another variable also references, then being surprised both changed.

Check yourself

  1. With # frozen_string_literal: true, what happens on s = "abc"; s << "d"?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.ruby-lang.org/en/3.4/String.html

Builds on

Unlocks

Nothing builds on this yet.