-
Notifications
You must be signed in to change notification settings - Fork 0
MR05 Input Lab Solution
In this solution, we'll learn about the following:
- Using
gets
to capture user input - The difference between
print
andputs
- String interpolation
- The differences between single-quoted and double-quoted string literals
String#strip
String#chomp
This was our assignment:
Prompt the user for the following pieces of data regarding a single mutant:
- Real name (e.g. Aurelia)
- Mutant name (e.g. Razorsnake)
- Power (e.g. Razor-sharp scales)
Print something back to the screen to prove you got all of the information.
Let's break it down.
Prompt the user
For a prompt, we'll print something to the screen. We can use our old friend puts
:
puts 'Real name: '
Then we need to capture the user's input, which we do with gets
. We'll need to save it to a variable in order to use it later.
puts 'Real name: '
real_name = gets
Local variable names must start with a lowercase letter. It is conventional for variable names to be all lowercase, with underscores separating multiple words.
Let's go ahead and add a line to prove we really did set the real_name
to the user's input.
We can do it with string concatenation...
puts 'This mutant\'s real name is ' + real_name
...or string interpolation.
puts "This mutant's real name is #{real_name}."
String interpolation (with the #{...}
syntax) only works in double-quoted string literals. The interpolated section doesn't have to be a single variable; it can be any Ruby expression.
Interpolation and a need to escape special characters like \n
are the primary reasons to use double-quoted string literals. It is common to use single quotes wherever those features are not needed.
Here's what we have so far:
roster.rb
#!/usr/bin/env ruby
puts 'Hello, mutant collector!'
puts 'Real name: '
real_name = gets
puts "This mutant's real name is #{real_name}."
Let's run it!
./roster.rb
Hello, mutant collector!
Real name:
Aurelia
This mutant's real name is Aurelia
.
There are a few things I'm not thrilled with, but the biggest problem is that the period at the end is on its own line. That's because gets
includes the line-break entered by the user it the resulting string. So real_name
contains "Aurelia\n"
.
We could use String#strip
to remove whitespace from the beginning and end of the string. There's also rstrip
, which removes whitespace only from the end.
String#chomp
, without any arguments is probably the best fit for what we're doing here. It will remove a trailing line break (either "\n"
or "\r\n"
) from the end of the string.
We could call chomp when we print the result to the screen...
puts "This mutant's real name is #{real_name.chomp}."
...but it probably makes more sense to chain chomp
on the end of gets
when we first assign the string.
real_name = gets.chomp
Let's run it again.
$ ./roster.rb
Hello, mutant collector!
Real name:
Aurelia
This mutant's real name is Aurelia.
That's much better, but there is one other thing bothering me: I think it would look nicer if the user entered the name on the same line as the prompt, like this:
Real name: Aurelia
That's an easy enough fix. We can use print
in place of puts
. The former prints the string as-is, while the latter adds a newline to the end if one is not already there.
Let's change our prompt...
print 'Real name: '
...and run it again.
./roster.rb
Hello, mutant collector!
Real name: Aurelia
This mutant's real name is Aurelia.
Beautiful!
Now it's easy enough to build it out with the other two pieces of data.
#!/usr/bin/env ruby
puts 'Hello, mutant collector!'
print 'Real name: '
real_name = gets.chomp
print 'Mutant name: '
mutant_name = gets.chomp
print 'Power: '
power = gets.chomp
puts "#{mutant_name} (also known as #{real_name}) has an incredible power: #{power}."
Seems to do the trick:
$ ./roster.rb
Hello, mutant collector!
Real name: Aurelia
Mutant name: Razorsnake
Power: Razor-sharp scales
Razorsnake (also known as Aurelia) has an incredible power: Razor-sharp scales.
That's worth a commit! Before committing, review the changes you've made since the previous commit.
$ git diff
diff --git a/roster.rb b/roster.rb
index d4f7211..a8a1fa1 100755
--- a/roster.rb
+++ b/roster.rb
@@ -1,2 +1,10 @@
#!/usr/bin/env ruby
puts 'Hello, mutant collector!'
+
+print 'Real name: '
+real_name = gets.chomp
+print 'Mutant name: '
+mutant_name = gets.chomp
+print 'Power: '
+power = gets.chomp
+puts "#{mutant_name} (also known as #{real_name}) has an incredible power: #{power}."
All we did was add new lines to our script. We didn't change any existing lines. Looks ready to commit.
$ git add .
$ git commit -m "Prompt for a mutant's real name, mutant name, and power."
We know Ruby is supposed to be object-oriented, but this script doesn't seem particularly object-oriented. What exactly is going on here anyway? Let's dig in and find out.