Ruby wizardry, p.3
Ruby Wizardry, page 3
18
Don’t worry about the 22 and the 4 being repeated back to you; Ruby’s just trying to be helpful. Ruby always expects the variable name to be on the left and the value to be on the right, so make sure not to mix up the order!
You’ll also notice I used _ (called an underscore) instead of a space in the variable names. Ruby doesn’t allow spaces in names, so it’s a good practice to use _ instead.
It sounds like the King is still getting the hang of strings (imagine my ear pressed to the heavy oak door of his study), so I’ll clue you in on one more bit of Ruby magic. When you see code like this:
>> 'Property of His Royal Highness, the King'.reverse
it means you’re calling the reverse method on the string. When we say we’re “calling a method,” what we mean is we’re asking Ruby to carry out a command: “Hey, Ruby! Reverse this string for me, please!” I’ll go on and on about methods later, but for now, you can think of them as commands that work on particular Ruby objects. For example, strings can be reversed, but numbers can’t:
>> "18".reverse => "81" >> 18.reverse => NoMethodError: undefined method `reverse' for 18:Fixnum
NoMethodError!? That’s Ruby saying, “Whoa, whoa, whoa. I know how to reverse a string, but I don’t know how to reverse a number!” As you practice, you’ll get to know which methods go with which kinds of Ruby objects. Author’s honor. (I was never a scout.)
Ruby Operators
“Let me see if I’ve got this right,” said the King. “Variables are names for Ruby values, like strings and numbers. They don’t have quotes around them and can’t have spaces in them. I can use the equal sign to set a variable equal to a value, and then I can use my variable’s name to get that value back.”
“That’s exactly right,” said Ruben.
“And when I see an object followed by a dot followed by a command, that means I’m using that command on that object,” said the King.
“Precisely,” said Scarlet.
“You mentioned that I can’t reverse a number,” said the King. “That makes sense. But what can I do to a number?”
“All sorts of things,” said Ruben. He nudged Scarlet aside and typed at the Computing Contraption:
>> 100 + 17 => 117 >> 50 - 20 => 30 >> 10 * 10 => 100 >> 40 / 20 => 2
“Yes, yes,” said the King. “I can add them with +, subtract them with -, multiply them with *, and divide them with /.”
“You’ve probably seen ÷ for division,” Ruben continued, “but in code we can just use /. For example, 4 ÷ 2 will be 4 / 2.”
“But what can I do that’s interesting?” the King complained.
“What about this?” asked Ruben, as he typed some more.
>> 22.next => 23 >> 22.pred => 21
“Aha!” said the King. “Now you’re talking. next must tell Ruby to calculate the next number, and pred asks Ruby for its predecessor, which is the number that comes right before it.”
“Right as rain,” said Ruben.
“RAIN!” exclaimed the King, jumping up so forcefully that he knocked his solid gold armchair right over. He ran out of the room at what seemed an impossible speed for a man of his age, and Ruben and Scarlet followed.
After running for several minutes through the horribly jumbled contents of the palace (the King had turned it upside-down, after all), Ruben and Scarlet caught up with the King in his main bathroom. He was weeping again, but this time with joy, and clutched in his hands was—his string!
“Rain reminded me that I took a refreshing shower after my breakfast of parched oats!” blubbered the King. “And here it was, hanging to dry, just as I’d left it. I can’t thank you enough!”
“Careful!” said Scarlet. “Your string’s still a bit wet; look at the beads sliding around on it.”
The King sniffed loudly and inspected his string, and the characters on it were, in fact, sliding every which way. The King thought for a moment, then double-knotted each end of the string to keep his characters from sliding off:
"Property of His Royal Highness, the King"
“Double quotes!” said Scarlet. “Can you use those with Ruby strings?”
“Definitely,” said Ruben, “and single- and double-quoted strings work almost exactly the same way.” He pried open the King’s medicine cabinet to expose a slightly-less-old Computing Contraption, then typed the following:
>> double_quotes = "A string's the thing" => "A string's the thing" >> single_quotes = 'for a springly King' => "for a springly King"
“See?” said Ruben. “Even when we type single quotes, Ruby repeats double quotes back to us. Both work!”
“Though I think I’ve heard tell,” said the King, “that you can put more complicated bits and trinkets in a double-quoted string than a single-quoted one.”
“That’s true,” said Ruben, “but we’ll get to that in good time.” And he closed the King’s medicine cabinet with a gold-plated click.
A Smallish Project for You
Now that you know a bit about strings, numbers, and variables, let’s put together a small project: writing a program to reflect and echo the King’s string. A reflection of something is just that thing backward, so you’ve probably already guessed that we’ll be reverse-ing some strings. On the other hand, an echo of something is just that thing repeated a few times, and we’ll soon see a way to repeat a string very quickly and easily. You’ll weep with joy at how simple and easy it is. You’ll tear out the pages of this book and use them to dry your tears.
Note
For some of the longer code examples, we’ll write Ruby scripts instead of using IRB! Whenever you see a filename in italics above the code, like kings_string.rb for the next example, that means you can write the code as a file with the given name and run it using the ruby command. Peek back at Chapter 1 if you don’t remember how to do this, or ask the nearest adult to help you. You can download all the scripts that appear in this book at http://nostarch.com/rubywizardry/. (But remember, if you’re learning to program, try typing things out yourself instead of just reading and running the code!)
Go ahead and make a new file called kings_string.rb. Then, open your file and type the following. We’re going to make a short program that shows off the cool things you can do by assigning variables and how Ruby can play with strings.
kings_string.rb
kings_string = "Property of His Royal Highness, the King" string_reflection = kings_string.reverse times_to_echo = 3 string_echo = kings_string * times_to_echo puts kings_string puts string_reflection puts string_echo
The first four lines are assigning variables. You can tell by the equal sign.
The second line in particular is pretty cool: it defines a variable to hold the kings_string, but because the reverse method makes the string backward, string_reflection will actually be "gniK eht ,ssenhgiH layoR siH fo ytreporP"!
You might be wondering about the fourth line of code, too:
string_echo = kings_string * times_to_echo
And you’re right to wonder! The * is the Ruby way of saying “multiply by.” This means 2 * 2 would equal 4, 13 * 379 would equal 4,927, and so on. But wait! you might further wonder, How can you multiply a string (which is just a bunch of letters) by a number? The answer is that Ruby is quite the clever robot. When it sees something like this:
>> "Hello!" * 3
it does this:
=> "Hello!Hello!Hello!"
So this is how we produce our echo: kings_string * times_to_echo will become "Property of His Royal Highness, the King" repeated three times!
puts is short for “put string,” as in “Put that string on the table where I can see it.” As we’ve seen, it just prints text on the screen. What do you think you’ll see when you run your program? Save and close your file, and then run it with ruby kings_string.rb. You should see the following output:
Property of His Royal Highness, the King gniK eht ,ssenhgiH layoR siH fo ytreporP Property of His Royal Highness, the KingProperty of His Royal Highness, the KingProperty of His Royal Highness, the King
Well done!
You Know This!
Let’s take a minute to review all the stuff you’ve packed into your brain over the last few pages.
We talked about strings and how they’re just words or phrases between quotes (single or double quotes are both fine). In fact, since the bits that make up a string don’t have to be just letters—they can include punctuation and even numbers, so long as the whole string is between quotes—we say that strings are made up of characters rather than letters. You can think of a string as a literal string of characters, with each end knotted with either single or double quotes. (You can pick single or double, but the ends have to match: "string' or 'string" won’t work!)
You also saw that strings have some handy methods, like length and reverse, which are just commands that Ruby knows how to use with strings. You always write the object you want to affect, followed by a dot, followed by the command, like this:
"gadzooks".length
We talked a bit about numbers, which are values in Ruby that work exactly like you think real-life numbers would. Numbers have their very own methods, which include next (for going to the next number) and pred (for going to the previous number):
>> 4.next => 5
Last, we talked about variables and how you can use them to give Ruby values special names, like 42 or "chunky bacon". You always write the variable name (which can’t contain spaces) on the left, followed by an equal sign, followed by the value:
>> bacon_consistency = "chunky" => "chunky" >> number_of_bacon_strips = 3 => 3
And you can get that value back just by typing its name:
>> bacon_consistency => "chunky"
Given what you know, how could you go further with that smallish project we tackled earlier? For instance, what if we changed the number of times_to_echo with next or pred? What would happen if we added a space on the end of the sentence we stored in kings_string? (Hint: It might make our output look nicer. But don’t put the space directly on the variable name kings_string—remember, Ruby variable names can’t have spaces!) What happens if we try to add a few different strings together with + instead of multiplying them by a number? And what in breakfast’s good name is chunky bacon, anyway?
Chapter 3. Pipe Dreams
The Apprentice Plumber’s Dilemma
The King, Scarlet, and Ruben made their way back from the Royal Bathroom, the King gleefully batting his string about like a big, beardy cat.
“All those waterworks for a string in a shower!” Scarlet said to the King. “I hope you’re feeling better now.”
“Much,” said the King, spinning the beads and trinkets on his string every which way.
“Speaking of waterworks,” said Ruben, “do you hear that?” And as they rounded the corner and reentered the King’s study, they found themselves ankle-deep in a miniature lake. There was water, water everywhere!
“The Mysterious Pipe!” cried the King. “Look!” And he pointed to the Mysterious Pipe, which was shaking violently and gushing a surprising amount of water from its narrow top.
“Check out the Flowmatic Something-or-Other!” said the King.
“That’s not terribly descriptive,” Ruben said.
“No, that’s what it’s called,” said the King. “The Flowmatic Something-or-Other™.”
“Found it!” said Scarlet, grabbing a square metal box labeled HIS MAJESTY’S FLOWMATIC SOMETHING-OR-OTHER™ on the back of the Pipe. She pried open the cover of the Flowmatic Something-or-Other to find a miniature Computing Contraption with its glowing >> IRB prompt.
“What do I do?” Scarlet asked the King.
“I seem to recall this program uses a flowmatic_on variable,” the King said. “Try turning it off.” He paused a moment. “Hey! I remembered the stuff we learned about variables!”
Scarlet flashed the King a thumbs-up, typed at the prompt, and pressed ENTER:
>> flowmatic_on = false => false
The Mysterious Pipe shuddered once and sputtered, and the water stopped flowing.
“Whew!” said Ruben. “Nice work!” He peered over Scarlet’s shoulder at the screen. “How’d you do that? What’s false? It can’t be a string; there are no quotes around it. Is it also a variable?”
“Nope!” said Scarlet. “But it’s built into Ruby just like numbers, strings, and variables are. It’s called a Boolean, and there are actually two of them: true and false. It looks like the Mysterious Pipe works when flowmatic_on is true and shuts off when it’s false.”
“Then how was flowmatic_on true before?” Ruben asked.
“I don’t know!” said Scarlet. “Someone or something must have created that variable.”
“Well, it’s stopped leaking,” said the King, “but it’s not really fixed. It should work correctly even when flowmatic_on is true! After all, the Flowmatic supplies all the water to the castle; without it, there can be no Royal Baths, Royal Toothbrushings, or Royal Water Balloon Fights! We need the Mysterious Pipe and its Flowmatic to be on without leaking all over the place.”
“What about this?” Ruben said, pointing to a line on the Computing Contraption just below the Flowmatic’s on/off control:
Warning! flow_rate is above 50!
“The water must be coming into the Mysterious Pipe too fast,” said Scarlet.
“Gadzooks!” said the King. “The flow rate must be above 50!”
“What should we do?” asked Ruben.
The King thought for a minute. “I think it’s best that we do what should always be done in these situations,” he said. “We should call a professional. In this case, the Royal Plumber!”
Writing and Running Ruby Scripts
While the King calls the Royal Plumber, I’ll take a second to explain some more Ruby magic to you. Don’t worry, it won’t take but a minute.
You see, you don’t always have to type commands into IRB one at a time. As mentioned in Chapter 1, you can write a big block of Ruby code and save it as a Ruby script. Then, you can run your Ruby script in IRB! (This is a lot like running your code in the terminal with the ruby command, as we did in Chapter 1, but IRB will stay open the whole time.) Just start IRB while you’re in the folder that contains your Ruby script, then type load 'filename.rb'. That’s exactly the same as typing everything in the file into IRB—but this way it’s easy to make changes and try again!
Let’s try this little guy on for size. Type the following code in your favorite text editor and save it as a file called flow.rb. (Look back at Chapter 1 if you need a reminder of how to do this, and don’t worry—we’ll cover the new #{} syntax in two shakes of a fox’s tail.)
flow.rb
flow_rate = 100 puts "The flow rate is currently #{flow_rate}." flow_rate = 100 / 2 puts "Now the flow rate is #{flow_rate}!"
If you open IRB, type load 'flow.rb', and press ENTER, you should see:
>> load 'flow.rb' The flow rate is currently 100. Now the flow rate is 50! => true
Let’s walk through this line by line.
First, load 'flow.rb' (it doesn’t matter if you use single or double quotes here) tells Ruby to look for a file called flow.rb in the current directory (a directory is just a fancy name for a folder on your computer). If Ruby finds flow.rb and there are no problems with the code in the file, Ruby will run that code just as if you’d typed it bit by bit into IRB. Next, you know what flow_rate = 100 and puts do: the first one sets the flow_rate variable to the value 100, and puts prints out the string you give it. (You also get a bonus => true from Ruby, which lets you know that loading the file worked.) But you probably want to know: what’s this crazy-looking #{flow_rate} business?
Well, strings and variables are different things, but sometimes you might want to combine them—say, to print out a message displaying different values for the flow_rate variable. Rather than making us look up the value of that variable and type it into the string by hand every time we want to use it, Ruby lets us use #{} to say, “Hey! Just insert the value of this variable right into the string.” So when you have:
flow_rate = 100 puts "The flow rate is currently #{flow_rate}."
you get:
The flow rate is currently 100.
One last thing: remember in Chapter 2 when Ruben said that strings with double quotes (") were very slightly different from strings with single quotes (')? Well, the #{} magic (called string interpolation if you want to be super fancy) is possible only with double-quoted strings; it can’t be done with single-quoted ones. (This is precisely what the King meant in Chapter 2 when he said you could put more complicated bits and trinkets on a double-quoted string than on a single-quoted string.)
That’s really all I wanted to show you. And speaking of the King . . .
His Majesty’s Flow Control
“Hello?” said the King. (He had been on hold for a while.) “Is this the Royal Plumber?”
“Chuff! Chuff! Chuff!” said the Royal Plumber.
“Oh dear,” said the King. “It sounds like the Royal Plumber has come down with a bad case of the Chuffs.”
“Chuffs?” said Scarlet.
“Chuff!” said the Royal Plumber.
“It’s a bit like a cold, but coughier and huffier,” said the King. “Royal Plumber, could you send down your Apprentice to help us with the Mysterious Pipe? It’s been overflowing terribly.”
“Chuff!” she said, and hung up.
“I think that was a yes,” said the King.
“I think so, too,” said Ruben. “It looks like the Apprentice is already here!”
The Apprentice to the Royal Plumber strolled into the King’s study carrying a large red toolbox. Ruben and Scarlet found his expression hard to read behind his dark rectangular sunglasses and heavy black beard. The name Haldo was stitched in red on the front of his coveralls.
Don’t worry about the 22 and the 4 being repeated back to you; Ruby’s just trying to be helpful. Ruby always expects the variable name to be on the left and the value to be on the right, so make sure not to mix up the order!
You’ll also notice I used _ (called an underscore) instead of a space in the variable names. Ruby doesn’t allow spaces in names, so it’s a good practice to use _ instead.
It sounds like the King is still getting the hang of strings (imagine my ear pressed to the heavy oak door of his study), so I’ll clue you in on one more bit of Ruby magic. When you see code like this:
>> 'Property of His Royal Highness, the King'.reverse
it means you’re calling the reverse method on the string. When we say we’re “calling a method,” what we mean is we’re asking Ruby to carry out a command: “Hey, Ruby! Reverse this string for me, please!” I’ll go on and on about methods later, but for now, you can think of them as commands that work on particular Ruby objects. For example, strings can be reversed, but numbers can’t:
>> "18".reverse => "81" >> 18.reverse => NoMethodError: undefined method `reverse' for 18:Fixnum
NoMethodError!? That’s Ruby saying, “Whoa, whoa, whoa. I know how to reverse a string, but I don’t know how to reverse a number!” As you practice, you’ll get to know which methods go with which kinds of Ruby objects. Author’s honor. (I was never a scout.)
Ruby Operators
“Let me see if I’ve got this right,” said the King. “Variables are names for Ruby values, like strings and numbers. They don’t have quotes around them and can’t have spaces in them. I can use the equal sign to set a variable equal to a value, and then I can use my variable’s name to get that value back.”
“That’s exactly right,” said Ruben.
“And when I see an object followed by a dot followed by a command, that means I’m using that command on that object,” said the King.
“Precisely,” said Scarlet.
“You mentioned that I can’t reverse a number,” said the King. “That makes sense. But what can I do to a number?”
“All sorts of things,” said Ruben. He nudged Scarlet aside and typed at the Computing Contraption:
>> 100 + 17 => 117 >> 50 - 20 => 30 >> 10 * 10 => 100 >> 40 / 20 => 2
“Yes, yes,” said the King. “I can add them with +, subtract them with -, multiply them with *, and divide them with /.”
“You’ve probably seen ÷ for division,” Ruben continued, “but in code we can just use /. For example, 4 ÷ 2 will be 4 / 2.”
“But what can I do that’s interesting?” the King complained.
“What about this?” asked Ruben, as he typed some more.
>> 22.next => 23 >> 22.pred => 21
“Aha!” said the King. “Now you’re talking. next must tell Ruby to calculate the next number, and pred asks Ruby for its predecessor, which is the number that comes right before it.”
“Right as rain,” said Ruben.
“RAIN!” exclaimed the King, jumping up so forcefully that he knocked his solid gold armchair right over. He ran out of the room at what seemed an impossible speed for a man of his age, and Ruben and Scarlet followed.
After running for several minutes through the horribly jumbled contents of the palace (the King had turned it upside-down, after all), Ruben and Scarlet caught up with the King in his main bathroom. He was weeping again, but this time with joy, and clutched in his hands was—his string!
“Rain reminded me that I took a refreshing shower after my breakfast of parched oats!” blubbered the King. “And here it was, hanging to dry, just as I’d left it. I can’t thank you enough!”
“Careful!” said Scarlet. “Your string’s still a bit wet; look at the beads sliding around on it.”
The King sniffed loudly and inspected his string, and the characters on it were, in fact, sliding every which way. The King thought for a moment, then double-knotted each end of the string to keep his characters from sliding off:
"Property of His Royal Highness, the King"
“Double quotes!” said Scarlet. “Can you use those with Ruby strings?”
“Definitely,” said Ruben, “and single- and double-quoted strings work almost exactly the same way.” He pried open the King’s medicine cabinet to expose a slightly-less-old Computing Contraption, then typed the following:
>> double_quotes = "A string's the thing" => "A string's the thing" >> single_quotes = 'for a springly King' => "for a springly King"
“See?” said Ruben. “Even when we type single quotes, Ruby repeats double quotes back to us. Both work!”
“Though I think I’ve heard tell,” said the King, “that you can put more complicated bits and trinkets in a double-quoted string than a single-quoted one.”
“That’s true,” said Ruben, “but we’ll get to that in good time.” And he closed the King’s medicine cabinet with a gold-plated click.
A Smallish Project for You
Now that you know a bit about strings, numbers, and variables, let’s put together a small project: writing a program to reflect and echo the King’s string. A reflection of something is just that thing backward, so you’ve probably already guessed that we’ll be reverse-ing some strings. On the other hand, an echo of something is just that thing repeated a few times, and we’ll soon see a way to repeat a string very quickly and easily. You’ll weep with joy at how simple and easy it is. You’ll tear out the pages of this book and use them to dry your tears.
Note
For some of the longer code examples, we’ll write Ruby scripts instead of using IRB! Whenever you see a filename in italics above the code, like kings_string.rb for the next example, that means you can write the code as a file with the given name and run it using the ruby command. Peek back at Chapter 1 if you don’t remember how to do this, or ask the nearest adult to help you. You can download all the scripts that appear in this book at http://nostarch.com/rubywizardry/. (But remember, if you’re learning to program, try typing things out yourself instead of just reading and running the code!)
Go ahead and make a new file called kings_string.rb. Then, open your file and type the following. We’re going to make a short program that shows off the cool things you can do by assigning variables and how Ruby can play with strings.
kings_string.rb
kings_string = "Property of His Royal Highness, the King" string_reflection = kings_string.reverse times_to_echo = 3 string_echo = kings_string * times_to_echo puts kings_string puts string_reflection puts string_echo
The first four lines are assigning variables. You can tell by the equal sign.
The second line in particular is pretty cool: it defines a variable to hold the kings_string, but because the reverse method makes the string backward, string_reflection will actually be "gniK eht ,ssenhgiH layoR siH fo ytreporP"!
You might be wondering about the fourth line of code, too:
string_echo = kings_string * times_to_echo
And you’re right to wonder! The * is the Ruby way of saying “multiply by.” This means 2 * 2 would equal 4, 13 * 379 would equal 4,927, and so on. But wait! you might further wonder, How can you multiply a string (which is just a bunch of letters) by a number? The answer is that Ruby is quite the clever robot. When it sees something like this:
>> "Hello!" * 3
it does this:
=> "Hello!Hello!Hello!"
So this is how we produce our echo: kings_string * times_to_echo will become "Property of His Royal Highness, the King" repeated three times!
puts is short for “put string,” as in “Put that string on the table where I can see it.” As we’ve seen, it just prints text on the screen. What do you think you’ll see when you run your program? Save and close your file, and then run it with ruby kings_string.rb. You should see the following output:
Property of His Royal Highness, the King gniK eht ,ssenhgiH layoR siH fo ytreporP Property of His Royal Highness, the KingProperty of His Royal Highness, the KingProperty of His Royal Highness, the King
Well done!
You Know This!
Let’s take a minute to review all the stuff you’ve packed into your brain over the last few pages.
We talked about strings and how they’re just words or phrases between quotes (single or double quotes are both fine). In fact, since the bits that make up a string don’t have to be just letters—they can include punctuation and even numbers, so long as the whole string is between quotes—we say that strings are made up of characters rather than letters. You can think of a string as a literal string of characters, with each end knotted with either single or double quotes. (You can pick single or double, but the ends have to match: "string' or 'string" won’t work!)
You also saw that strings have some handy methods, like length and reverse, which are just commands that Ruby knows how to use with strings. You always write the object you want to affect, followed by a dot, followed by the command, like this:
"gadzooks".length
We talked a bit about numbers, which are values in Ruby that work exactly like you think real-life numbers would. Numbers have their very own methods, which include next (for going to the next number) and pred (for going to the previous number):
>> 4.next => 5
Last, we talked about variables and how you can use them to give Ruby values special names, like 42 or "chunky bacon". You always write the variable name (which can’t contain spaces) on the left, followed by an equal sign, followed by the value:
>> bacon_consistency = "chunky" => "chunky" >> number_of_bacon_strips = 3 => 3
And you can get that value back just by typing its name:
>> bacon_consistency => "chunky"
Given what you know, how could you go further with that smallish project we tackled earlier? For instance, what if we changed the number of times_to_echo with next or pred? What would happen if we added a space on the end of the sentence we stored in kings_string? (Hint: It might make our output look nicer. But don’t put the space directly on the variable name kings_string—remember, Ruby variable names can’t have spaces!) What happens if we try to add a few different strings together with + instead of multiplying them by a number? And what in breakfast’s good name is chunky bacon, anyway?
Chapter 3. Pipe Dreams
The Apprentice Plumber’s Dilemma
The King, Scarlet, and Ruben made their way back from the Royal Bathroom, the King gleefully batting his string about like a big, beardy cat.
“All those waterworks for a string in a shower!” Scarlet said to the King. “I hope you’re feeling better now.”
“Much,” said the King, spinning the beads and trinkets on his string every which way.
“Speaking of waterworks,” said Ruben, “do you hear that?” And as they rounded the corner and reentered the King’s study, they found themselves ankle-deep in a miniature lake. There was water, water everywhere!
“The Mysterious Pipe!” cried the King. “Look!” And he pointed to the Mysterious Pipe, which was shaking violently and gushing a surprising amount of water from its narrow top.
“Check out the Flowmatic Something-or-Other!” said the King.
“That’s not terribly descriptive,” Ruben said.
“No, that’s what it’s called,” said the King. “The Flowmatic Something-or-Other™.”
“Found it!” said Scarlet, grabbing a square metal box labeled HIS MAJESTY’S FLOWMATIC SOMETHING-OR-OTHER™ on the back of the Pipe. She pried open the cover of the Flowmatic Something-or-Other to find a miniature Computing Contraption with its glowing >> IRB prompt.
“What do I do?” Scarlet asked the King.
“I seem to recall this program uses a flowmatic_on variable,” the King said. “Try turning it off.” He paused a moment. “Hey! I remembered the stuff we learned about variables!”
Scarlet flashed the King a thumbs-up, typed at the prompt, and pressed ENTER:
>> flowmatic_on = false => false
The Mysterious Pipe shuddered once and sputtered, and the water stopped flowing.
“Whew!” said Ruben. “Nice work!” He peered over Scarlet’s shoulder at the screen. “How’d you do that? What’s false? It can’t be a string; there are no quotes around it. Is it also a variable?”
“Nope!” said Scarlet. “But it’s built into Ruby just like numbers, strings, and variables are. It’s called a Boolean, and there are actually two of them: true and false. It looks like the Mysterious Pipe works when flowmatic_on is true and shuts off when it’s false.”
“Then how was flowmatic_on true before?” Ruben asked.
“I don’t know!” said Scarlet. “Someone or something must have created that variable.”
“Well, it’s stopped leaking,” said the King, “but it’s not really fixed. It should work correctly even when flowmatic_on is true! After all, the Flowmatic supplies all the water to the castle; without it, there can be no Royal Baths, Royal Toothbrushings, or Royal Water Balloon Fights! We need the Mysterious Pipe and its Flowmatic to be on without leaking all over the place.”
“What about this?” Ruben said, pointing to a line on the Computing Contraption just below the Flowmatic’s on/off control:
Warning! flow_rate is above 50!
“The water must be coming into the Mysterious Pipe too fast,” said Scarlet.
“Gadzooks!” said the King. “The flow rate must be above 50!”
“What should we do?” asked Ruben.
The King thought for a minute. “I think it’s best that we do what should always be done in these situations,” he said. “We should call a professional. In this case, the Royal Plumber!”
Writing and Running Ruby Scripts
While the King calls the Royal Plumber, I’ll take a second to explain some more Ruby magic to you. Don’t worry, it won’t take but a minute.
You see, you don’t always have to type commands into IRB one at a time. As mentioned in Chapter 1, you can write a big block of Ruby code and save it as a Ruby script. Then, you can run your Ruby script in IRB! (This is a lot like running your code in the terminal with the ruby command, as we did in Chapter 1, but IRB will stay open the whole time.) Just start IRB while you’re in the folder that contains your Ruby script, then type load 'filename.rb'. That’s exactly the same as typing everything in the file into IRB—but this way it’s easy to make changes and try again!
Let’s try this little guy on for size. Type the following code in your favorite text editor and save it as a file called flow.rb. (Look back at Chapter 1 if you need a reminder of how to do this, and don’t worry—we’ll cover the new #{} syntax in two shakes of a fox’s tail.)
flow.rb
flow_rate = 100 puts "The flow rate is currently #{flow_rate}." flow_rate = 100 / 2 puts "Now the flow rate is #{flow_rate}!"
If you open IRB, type load 'flow.rb', and press ENTER, you should see:
>> load 'flow.rb' The flow rate is currently 100. Now the flow rate is 50! => true
Let’s walk through this line by line.
First, load 'flow.rb' (it doesn’t matter if you use single or double quotes here) tells Ruby to look for a file called flow.rb in the current directory (a directory is just a fancy name for a folder on your computer). If Ruby finds flow.rb and there are no problems with the code in the file, Ruby will run that code just as if you’d typed it bit by bit into IRB. Next, you know what flow_rate = 100 and puts do: the first one sets the flow_rate variable to the value 100, and puts prints out the string you give it. (You also get a bonus => true from Ruby, which lets you know that loading the file worked.) But you probably want to know: what’s this crazy-looking #{flow_rate} business?
Well, strings and variables are different things, but sometimes you might want to combine them—say, to print out a message displaying different values for the flow_rate variable. Rather than making us look up the value of that variable and type it into the string by hand every time we want to use it, Ruby lets us use #{} to say, “Hey! Just insert the value of this variable right into the string.” So when you have:
flow_rate = 100 puts "The flow rate is currently #{flow_rate}."
you get:
The flow rate is currently 100.
One last thing: remember in Chapter 2 when Ruben said that strings with double quotes (") were very slightly different from strings with single quotes (')? Well, the #{} magic (called string interpolation if you want to be super fancy) is possible only with double-quoted strings; it can’t be done with single-quoted ones. (This is precisely what the King meant in Chapter 2 when he said you could put more complicated bits and trinkets on a double-quoted string than on a single-quoted string.)
That’s really all I wanted to show you. And speaking of the King . . .
His Majesty’s Flow Control
“Hello?” said the King. (He had been on hold for a while.) “Is this the Royal Plumber?”
“Chuff! Chuff! Chuff!” said the Royal Plumber.
“Oh dear,” said the King. “It sounds like the Royal Plumber has come down with a bad case of the Chuffs.”
“Chuffs?” said Scarlet.
“Chuff!” said the Royal Plumber.
“It’s a bit like a cold, but coughier and huffier,” said the King. “Royal Plumber, could you send down your Apprentice to help us with the Mysterious Pipe? It’s been overflowing terribly.”
“Chuff!” she said, and hung up.
“I think that was a yes,” said the King.
“I think so, too,” said Ruben. “It looks like the Apprentice is already here!”
The Apprentice to the Royal Plumber strolled into the King’s study carrying a large red toolbox. Ruben and Scarlet found his expression hard to read behind his dark rectangular sunglasses and heavy black beard. The name Haldo was stitched in red on the front of his coveralls.
