A here document is an easy way to display a long, multiline string. This would have been PERFECT for use in my dungeon adventure. Here's how it works.
This is the original description from the first room in the dungeon game I built:
puts "This room is dimly lit by two sputtering torches."
puts "There are three doors leading out of here."
puts "What do you do?"
puts "There are three doors leading out of here."
puts "What do you do?"
You may notice a few "puts" methods. It's not terrible in this case, since I'm putting several small statements, but it's tedious to type and unnecessary to use so many methods when you could do it with one here document. So forget what I said. There's a better, simpler way to do it, so it IS terrible!
So this example can be re-written like this:
puts <<−TORCH_DESCRIPTION
This room is dimly lit by two sputtering torches.
There are three doors leading out of here.
What do you do?
TORCH_DESCRIPTION
This room is dimly lit by two sputtering torches.
There are three doors leading out of here.
What do you do?
TORCH_DESCRIPTION
You begin the here document with <<−TORCH_DESCRIPTION and end it with TORCH_DESCRIPTION. Ruby interprets everything in between as one string. Cleaner, right? Easier to read? Who wouldn't love it!
On a side note, you CAN write this as <<TORCH_DESCRIPTION instead, but by adding the minus sign, you can indent the code as usual. Without the minus sign, the terminator can't be indented, or else Ruby will start complaining about "can't find string TORCH_DESCRIPTION anywhere before EOF".
So I recommend using the minus sign. One more character makes your code a lot easier to read. I also ran into another little problem. Since a here document is a string literal, any variables won't be interpreted correctly. This is where interpolation comes into play. Here's an example from the current exercise I'm working through.
guess = gets.chomp()
if guess != good_pod
puts "You jump into pod %s and hit the eject button." % guess
puts "The pod escapes out into the void of space, then"
puts "implodes as the hull ruptures, crushing your body"
puts "into jam jelly."
return :death
if guess != good_pod
puts "You jump into pod %s and hit the eject button." % guess
puts "The pod escapes out into the void of space, then"
puts "implodes as the hull ruptures, crushing your body"
puts "into jam jelly."
return :death
This bit of code describes an escape pod room, where the user has to pick an escape pod to use. So we set the user's choice as "guess" and then call it in the method below. This is what happens when a user chooses poorly. However, if I were to rewrite the code using a here document, this is what I'd have:
puts <<-BAD_POD
"You jump into escape pod %s and hit the eject button. %guess
The pod escapes out into the void of space, then
implodes as the hull ruptures, crushing your body
into a jelly."
BAD_POD
return :death
"You jump into escape pod %s and hit the eject button. %guess
The pod escapes out into the void of space, then
implodes as the hull ruptures, crushing your body
into a jelly."
BAD_POD
return :death
Now the %s and %guess won't be interpreted as variables, since they're inside of a string literal. Luckily, there's an easy solution: interpolation. Just swap out the %s for this little guy:
#{guess}
Ruby will look at this, understand that means you want to use a variable inside of a string literal, and then pull the information it collected when it asked the user which pod he wanted to jump into.
I'm hoping this post will be helpful for others who are grappling with here documents. It took me a bit of digging to figure out how to get the code to index properly (since it looked awful in Textmate, and my solution was to put the string in quotes, which was unnecessary) and I needed to figure out how to call a variable from inside the here document.
No comments:
Post a Comment