Formatting strings and numbers
format and specifiers
format takes a template and the values, and returns a string. The specifiers are the C ones, so a reader coming from C or Python recognises them at once:
ruby -e 'puts format("%-10s %04d", "Ada", 42)'
Ada 0042
%-10s is a string in ten columns, left aligned; %04d is an integer in four columns padded with zeros. The percent operator does the same with the template on the left:
ruby -e 'puts "%-10s|" % "Ada"'
Ada |
A float takes a precision: %.2f prints two decimals and rounds, which is the line to use for a price or a timing. The % form and format produce the same string; pick one per project.
Width and alignment
For a table, the padding methods read better than a template: rjust and ljust take a width and an optional fill character, and center does both sides:
ruby -e 'puts "Ada".rjust(6, "."); puts "Ada".ljust(6, "."); puts "Ada".center(7, "-")'
...Ada
Ada...
--Ada--
A number pads the same way after to_s, which is the reason a column of numbers lines up only after the conversion.
A report from a heredoc
A multi-line report is a heredoc with interpolation, and the table from the previous section supplies the rows:
rows = [["Ada", 3], ["Bob", 12]]
puts <<~REPORT
Name Count
#{rows.map { |name, count| format("%-10s %3d", name, count) }.join("\n")}
REPORT
ruby report.rb
Name Count
Ada 3
Bob 12
<<~ strips the common indentation, so the heredoc can sit inside a method without leading spaces in the output. The inner format keeps the columns straight.
What to watch for
A template with the wrong number of values raises
ArgumentError; a template with the wrong type
raises TypeError. Both are better than a silently
shifted table, and both name the line.
Widths are characters, not display columns: a string with an emoji or a
wide character takes more terminal space than its length says. For a
table that must align, keep the cells to plain ASCII or accept the
wobble.
Next: Constants, globals and scope
Article author: Arthur Isaev