Ruby wizardry, p.15

Ruby Wizardry, page 15

 

Ruby Wizardry
Select Voice:
Brian (uk)
Emma (uk)  
Amy (uk)
Eric (us)
Ivy (us)
Joey (us)
Salli (us)  
Justin (us)
Jennifer (us)  
Kimberly (us)  
Kendra (us)
Russell (au)
Nicole (au)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

Larger Font   Reset Font Size   Smaller Font  

  “Bite your tongue!” said the King. “Haldo’s been in my service since he was a boy. He’d never do anything to hurt us or this kingdom!”

  “We should consider every possibility,” Scarlet said.

  “Even so,” said the King, “all suspects are innocent until we prove them guilty. If we’re lucky, we’ll catch these scoundrels red-handed when we arrive at the castle!”

  “Which will be any minute,” Ruben said. “Look!”

  Up ahead, the narrow tunnel opened up into a wide cavern. The King, Scarlet, and Ruben jogged into the open space, then stood for a moment, catching their breath.

  “This is it,” said the King, “the basement below the basement below the castle! Now we just need to find the Mysterious Pipe and climb back up into my Royal Study.”

  “And there it is!” said Scarlet. In the darkness, they could just make out the outline of the Mysterious Pipe in the far corner.

  The trio walked up to the base of the pipe, which was gurgling softly.

  “Now what?” asked Ruben. “The Mysterious Pipe is full of water! How are we supposed to climb up it?”

  “Well, we turned the Flowmatic Something-or-Other on before,” Scarlet said. “We can turn it back off!” She felt around the bottom of the pipe until she found the familiar boxy shape of a Computing Contraption, then flipped open its lid. The glow of the IRB prompt illuminated their faces.

  “Right!” said the King. “What variable did we change before?”

  “flowmatic_on!” replied Ruben.

  Scarlet quickly typed into the Computing Contraption:

  >> flowmatic_on = false => false

  With a slow booooop and a glug-glug sound, the Mysterious Pipe shut down and emptied.

  “Well done, Scarlet!” said the King as he walked to the far side of the Pipe. He grabbed a large metal wheel jutting out of the side and gave it a spin. The wheel turned several times, and with a hollow clank, the door to which it was attached eased open.

  “Into the Mysterious Pipe!” cried the King, and the three climbed inside.

  Ruben looked straight up and squinted. “I can’t even see the light at the top!” he said. “This Pipe is huge! Hellooo!” he called, and the Mysterious Pipe echoed: Hello! Ello! Lo!

  “It’ll take forever to climb, if we can even do it at all!” said Scarlet. She thought for a moment. “I might have an idea.” She turned to Ruben and the King. “Do you trust me?” she asked.

  “With my life!” said the King.

  “To the end!” said Ruben.

  “All right, then,” said Scarlet. “Hold your breath!” She reached around to the Computing Contraption on the side of the Mysterious Pipe and typed:

  >> flowmatic_on = true

  She slammed the metal door shut, and in an instant, the pipe filled with water.

  For a moment, the three floated at the bottom of the Mysterious Pipe, holding their breath. Then the entire pipe began to tremble slightly, and with a deep whoosh, the force of the water propelled the King, Scarlet, and Ruben straight up!

  In just a few seconds, the three of them began to slow down, and they found themselves floating just inches from the narrow top of the Mysterious Pipe. The King reached down and pushed on the latch of the pipe’s door, and in a flood of water, the trio tumbled out onto the floor of the King’s Royal Study.

  “Genius! Absolutely genius!” the King sputtered.

  “Thank you,” said Scarlet, taking a small bow. “But we’ve got to get to the Queen! Do you know where she is?”

  “She should be back from Her Royal Majesty’s Hacktastic Ruby Conference,” said the King, “so I imagine she’s up in her Royal Office. Let’s go!” And with that, he dashed out of the room.

  Ruby and Scarlet followed. “The Queen was at a Ruby conference?” Scarlet asked as they raced up the stairs.

  “Indeed!” said the King. “It might surprise you to learn that although I’m rather new to all of this Ruby business, my wife is quite the hacker.”

  “That’s amazing!” said Ruben. “Maybe she’ll be able to help us fix all these Ruby malfunctions and catch the bad guys causing them.”

  “I hope so. Ah! Here we are,” said the King, and he skidded to a halt in front of an enormous wooden door with golden handles.

  He pulled down on both handles at once, swung the doors open, and rushed inside.

  The Queen was seated at her desk in a high-backed chair, furiously typing at a Computing Contraption.

  “They tried to break into my Computing Contraption!” she said. “The very idea!”

  “They who?” asked Scarlet and Ruben together as they followed the King into the Queen’s Royal Office.

  “I don’t know!” said the Queen, still typing. “There were four of them, and I caught them at my Computing Contraption, trying to figure out my password. Luckily, I’m a stickler for security.”

  “That she is,” said the King, wringing out his fluffy white beard. “She won’t even let me buy gummy bears on the Internet!”

  “For good reason,” said the Queen, and she stopped typing. “The last time I let you do that, you sent a small fortune to someone claiming to be the Gummy Bear King!” She paused, looking at Scarlet and Ruben. “I don’t believe we’ve met,” she said. “Who might you be?” She looked the three of them up and down. “And why are you all so wet?”

  “I’m Ruben,” said Ruben, “and this is Scarlet. We’re helping the King find whoever’s responsible for all the Ruby malfunctions going on, and we ran all the way from the Carmine Pines and swam up through the Mysterious Pipe to do it!”

  “Well, you’ve come to the right place!” said the Queen. “I’m going to track down those ne’er-do-wells if it’s the last thing I do.” She began typing again.

  “Did you get a good look at any of them?” asked Scarlet. “Were there any clues? Did you see or hear anything that might help us catch them?”

  “I didn’t see their faces,” the Queen said, “but I overheard them trying to figure out my Computing Contraption’s password. There were four of them—it sounded like two boys and two girls. I got home early from the Hacktastic Ruby Conference and thought I’d try out some of the Ruby tricks I learned, and when I came up to my office, I caught them in the act! They ran when I shouted at them to surrender, and I sent the palace guards after them. In the meantime, I’ve been working to increase the security on my Computing Contraption to ensure it’s completely immune to attack.”

  “Did they get anything from your Computing Contraption?” Scarlet asked.

  “Thank heavens, no,” said the Queen. “They didn’t get my password, but we’d be in terrible trouble if they had. With that, they could access any system in the kingdom with no restrictions!”

  “These villains are escalating!” said the King, pacing around the Queen’s office. “We’ve got to catch them as quickly as possible, before they strike again. We might not be so lucky next time.”

  The Queen nodded. “I’ve instructed the guards to bring any suspects they catch directly to us for questioning,” she said. “In the meantime, I’ve upgraded all the security on my Computing Contraption. The only thing left to do is update some of my Ruby programs to make them more secure, too!”

  “Ruby!” said Ruben. “That happens to be our specialty. Can we help?” he asked.

  The Queen smiled. “That would be lovely,” she said. “While I’m something of an expert in more than a few programming languages, I’m pretty new to Ruby.” She slid over in her chair, and Ruben and Scarlet clambered up beside her.

  “First things first,” said the Queen. “Do you know how to create a Ruby class?”

  A Brush-up on Classes

  “I think so,” said Ruben. “May I create any class I want?” The Queen nodded, and Ruben typed into her Computing Contraption:

  >> class Animal >> attr_accessor :name >> >> def initialize(name, legs=4) >> @name = name >> @legs = legs >> end >> end => nil

  “I see!” said the Queen. “You’ve defined an Animal class. You’re using attr_accessor to automatically make a method to access the names of your animals, and the initialize method sets the animal’s @name and number of @legs whenever a new animal is created.”

  “Yup!” said Ruben. “And if we create an animal with Animal.new but don’t give it a number of legs, it’ll be 4 by default.”

  The Queen nodded. “That makes sense to me. Why don’t you go ahead and create a couple of animals?”

  Ruben typed some more:

  ➊ >> monkey = Animal.new('George', 2) => # ➋ >> monkey.name = 'Kong' => "Kong" ➌ >> dog = Animal.new('Bigelow') => #

  “Wonderful! At ➊, we’ve created monkey, an instance of the Animal class, and created it with the name 'George' and 2 legs. Next, at ➋, we’ve changed our monkey’s name to 'Kong' to show that our attr_accessor lets us both read and change the name.

  “Finally, at ➌, we’ve created a second instance of the Animal class, dog, with the name 'Bigelow'. Since we didn’t create our dog with a number of legs, it gets four by default, as you can see by the return value at ➍.”

  A Couple of Classes

  The Queen thought for a moment. “Yes, this will do nicely. Now then,” she continued, “imagine if instead of just having monkey and dog as instances of Animal, we decided we wanted to have Monkey and Dog as separate classes instead. How could we do it?”

  “Well, we could do something like this,” Ruben said, and he typed:

  >> class Monkey >> attr_accessor :name >> >> def initialize(name) >> @name = name >> @legs = 2 >> end >> end => nil

  “Precisely,” said the Queen. “That defines a Monkey class, and the monkeys it creates will have @names and two @legs. The attr_accessor also automatically creates a name method for each monkey so we can get its name. To create a new monkey from the class, we use Monkey.new and pass its name as a string value. Like this!” She typed into the Computing Contraption:

  >> monkey = Monkey.new('George') => # >> monkey.name => "George"

  “We can do the same thing for our Dog class,” Ruben continued. “We know that pretty much every dog has four legs, so it’ll look just like the Monkey class, only the class name will be different and the number of @legs will be 4.” He typed into the Computing Contraption:

  >> class Dog >> attr_accessor :name >> >> def initialize(name) >> @name = name >> @legs = 4 >> end >> end => nil

  “Just like we can create new monkeys with Monkey.new and pass in a string for the monkey’s name, we can create new dogs with Dog.new and pass in a string for the dog’s name!” Ruben said.

  >> dog = Dog.new('Bigelow') => # >> dog.name => "Bigelow"

  “That’s certainly one way to create a couple of classes,” said the Queen, “but it looks like you had to write a lot of the same code for both your Monkey and your Dog class.”

  “That’s true,” said Ruben. “Is that okay?”

  Inheritance and DRY Code

  “Well,” said the Queen, “any time you find yourself writing something more than once, you should ask yourself whether you have to. Good code—unlike my husband here,” she said, stifling a laugh as the King poured water out of the sleeves of his kingly robe, “—should be DRY.”

  “I know that one!” said the King, shaking drops of water off his string and replacing it in his pocket. “It stands for Don’t Repeat Yourself.”

  “He knows that one because he repeats himself all the time,” the Queen whispered to Scarlet and Ruben. “But yes,” she said, “if you avoid repeating yourself in your code, you save lots of time! Also, if you ever have to change something, you only need to change it one place, not several.”

  “I like the sound of that!” said Ruben, “but how can we make our class code more DRY?”

  “With inheritance,” said the Queen.

  “Inheritance!” said Scarlet. “I think I’ve heard it mentioned before, but I’m not sure what it is.”

  “I’ll show you,” said the Queen, explaining as she typed into the Computing Contraption. “We’ve already created a class called Animal. What if we could use that class as a way to create both our Monkey and Dog classes?”

  >> class Dog < Animal >> def bark >> puts 'Arf!' >> end >> end => nil

  “The class Dog < Animal part means that the Dog class inherits from the Animal class. It says to Ruby: ‘Make a new class called Dog that knows how to do everything Animal does,’” the Queen said. “Then we just add a method, like we’d normally do. Here, I’m adding a bark method for Dogs, since dogs know how to bark.” She rolled up her sleeves.

  “Here’s the amazing part: because Dog inherits from Animal, new dogs can do anything animals can do and anything dogs can do. They’ll have a name method and a default of four legs, and know how to bark!”

  >> dog = Dog.new('Bigelow') => # >> dog.name => "Bigelow" >> dog.bark Arf! => nil

  “Astounding!” said the King.

  “Isn’t it?” said the Queen. “It also means that instead of typing all that class definition business again for our Monkey class, we can just inherit from Animal again. Because we inherit from Animal, we get our name method and a default @legs value of 4, plus we’ll get this neat new make_sounds method I added just for monkeys.”

  >> class Monkey < Animal >> def make_sounds >> puts 'Eeh ooh ooh!' >> end >> end => nil

  “Now we can create a new monkey with a name and two legs. Not only can we change its name with the name= method we inherited from Animal, but we can also make_sounds!”

  “We can get the name and change it?” Ruben asked.

  The Queen nodded. “Remember, we inherited from Animal, and Animal has attr_accessor :name. That automatically creates a name method for getting the name and a name= method for setting the name. See?”

  >> monkey = Monkey.new('George', 2) => # >> monkey.name = 'Oxnard' => "Oxnard" >> monkey.make_sounds Eeh ooh ooh! => nil

  “Wow!” said Scarlet, “That’s amazing—the monkey and the dog have their own methods, but they also can do anything an Animal can do!”

  “That’s what makes inheritance so wonderful!” said the Queen. “Given our Animal class from before, which had an attr_accessor for :name and an initialize method that set the @name and @legs instance variables, we can make two new classes that inherit that information and add some new things—like a bark method for Dog instances and a make_sounds method for Monkey instances.

  “Inheritance in Ruby works exactly as it does in real life,” the Queen continued. “Just like you might have inherited your father’s eye color or your mother’s math smarts, objects in Ruby can inherit information and methods from other objects.”

  “Oh!” said Ruben. “So not only can we use classes to create lots of similar objects and avoid writing extra code, but we can even write classes that borrow code from other classes?”

  “On the nose,” said the Queen. “We might want to use inheritance in our code if two classes have what I like to call an ‘is-a’ relationship, as in ‘a monkey is a kind of animal’ or ‘a dog is a kind of animal.’”

  “But a Dog would never inherit from a Monkey,” said Scarlet, “because a dog isn’t a kind of monkey.”

  “Exactly,” said the Queen.

  “Could you show us the syntax again?” said Scarlet. “This is a good trick and I want to remember it.”

  Subclass and Superclass

  “Of course,” said the Queen. “When you have one class that inherits from another, you use the class keyword, just like always. Then you write the name of the class that will inherit, which we call the subclass or the child class, and then a <. You can think of that little < as the tip of an arrow that says, ‘Put all the powers and abilities of the class on the right into the class on the left!’ To finish up, you then write the name of the class you’re inheriting from to the right of the <, which we call the superclass or parent class. Finally, you just define any new methods as you normally would. It looks like this,” she said, and typed:

  super_and_subclass.rb

  ➊ class MySuperclass def say_hello puts 'Hello!' end end ➋ class MySubclass < MySuperclass def say_goodbye puts 'Goodbye!' end end

  “Here we have two classes, MySuperclass and MySubclass,” the Queen explained. “MySubclass inherits from MySuperclass on line ➋, so instances of MySubclass not only have the say_goodbye method defined in the MySubclass class, but they can also use the say_hello method they inherit from MySuperclass! Let’s see what happens when we create a new instance of MySubclass.”

  >> load 'super_and_subclass.rb' => true >> subby = MySubclass.new => # >> subby.say_hello Hello! => nil >> subby.say_goodbye Goodbye! => nil

  “I created an instance of MySubclass called subby using MySubclass.new,” said the Queen. “Just like I promised, subby can use both the say_goodbye method defined in MySubclass as well as the say_hello method defined in MySuperclass, because MySubclass inherits from MySuperclass and can therefore do anything MySuperclass knows how to do.”

  “Thanks!” said Scarlet, “I think I’ve got it now.” She studied the screen for a few seconds. “Is it possible for a class to inherit from more than one other class?” she asked.

  “Alas, no,” said the Queen. “You can have only one class name on the left side of the < and one class name on the right side. However!” she continued, “there is a Ruby trick that lets you mix the behavior of several classes into one, which we’ll get to in a little while.”

  “Okay,” said Ruben, “but what if you want your subclass to have a different version of a method than the superclass has?”

 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
Add Fast Bookmark
Load Fast Bookmark
Turn Navi On
Turn Navi On
Turn Navi On
Scroll Up
Turn Navi On
Scroll
Turn Navi On
183