Exercise 7 of 10 · Strings and formatting
The Scoreboard
What you will make
A game scoreboard where every name, score and bar lands in the same column, no matter how long the name or how many digits the score has.
The one new idea: ljust and rjust pad a string to a fixed width so columns line up
Every receipt, timetable and leaderboard you have ever read is text lined up into columns. ljust and rjust are how Ruby does that, and reaching for them becomes automatic once you have used them once.
Go straight to the code ↓Padding text into columns
What lines text up into columns is padding: adding just enough spaces to a piece of text that it always ends up a fixed width, however long the text itself happens to be.
ljust(n) returns a copy of a string padded with spaces on the right until it is n characters wide, pushing the original text to the left. rjust(n) does the same but pads on the left, pushing the text to the right. Both only exist on strings — calling either one on a number raises an error, which is why a number is turned into text first with .to_s.
A worked example
fruit = "Fig"
count = 7
puts "[#{fruit.ljust(6)}][#{count.to_s.rjust(4)}]"
fruit = "Plum"
count = 112
puts "[#{fruit.ljust(6)}][#{count.to_s.rjust(4)}]"[Fig ][ 7]
[Plum ][ 112]The square brackets only exist so the padding is visible. Fig is three characters in a six-wide space, so three spaces trail it; Plum is four, so two do. Both closing brackets land in the same column regardless, and so do both numbers.
Your turn
The editor holds a scoreboard with three players on it. Press Run first: Ana and Ben print as tidy rows, but Cleo's row is ragged, because her line still joins the values with plain spaces instead of padding them.
Rewrite Cleo's line so it matches the shape of the two rows above it — same ljust, same rjust, same widths. Then try changing Cleo's score to 11 and run it again; her bar should grow and her row should stay in column, which is the proof the layout is being worked out rather than typed in.
If something goes wrong
If Ruby stops with NoMethodError mentioning rjust and Integer, a number is being padded directly instead of being turned into a string first — add .to_s before the .rjust.
If the row runs but sits in the wrong place, count the widths against the two finished rows rather than guessing. A name that drifts right, or a score pressed up against it with no space, means an ljust and rjust have been swapped, or the plain space between the two groups was dropped.
Write your code
Runs in your browser. Press Run (or Ctrl/Cmd+Enter) and the output is checked for you.
Press Esc then Tab to move keyboard focus out of the code editor.
Output will appear here after you run your code.The runtime is starting in the background. You can type now — it will be ready before you are.
The answer appears here once you have run your code at least once.
Things that often go wrong here
- Calling rjust directly on the number
- score.rjust(3) raises NoMethodError: undefined method 'rjust' for an Integer, because ljust and rjust only exist on strings. score.to_s.rjust(3) converts the number to text first, which is why every finished row does that conversion before padding it.
- Leaving plain spaces between the interpolated values instead of padding
- #{player} #{score} #{bar} puts exactly one space between each value, whatever length they happen to be, so a three-letter name and a four-letter name end up starting the score in different columns.
- Swapping ljust and rjust
- player.rjust(7) shoves the name to the right of its seven characters instead of the left, and score.to_s.ljust(3) does the same to the score, so the row still has the right width but the text sits jammed against the wrong edge of it.
- Choosing a width smaller than the longest name
- ljust and rjust never cut text short — a name longer than the width you gave it is printed in full, unpadded, and every row after it drifts out of column even though nothing else changed.
Want a blank editor instead? Open the Ruby playground.