The Magic of Methods and Blocks - Ruby Wizardry: An Introduction to Programming for Kids (2014)

Ruby Wizardry: An Introduction to Programming for Kids (2014)

Chapter 7. The Magic of Methods and Blocks

A Method to the Madness

“I think that’s the last of it!” Squeaky Jim said, sweeping a pile of stray hash into his dustpan. “That was some mid-morning rush!”

“I’ll say,” said Big Hank. He hefted a huge green compost bag onto his shoulder and grinned at the King, Scarlet, and Ruben. “Thanks for all your help today! We’d have been in a terrible pickle if you all hadn’t been here to lend a hand.”

“Our pleasure!” said Ruben, who was packing three to-go boxes of hash and eggs. “The food here is terrific!”

“Definitely!” said Scarlet. “Will you be okay for the lunch crowd? We had a lot of fun, and we can help some more if you need it.”

Hank laughed as he tossed bag after bag into the kitchen’s enormous compost bin. “The Hashery is more of a breakfast and brunch operation,” he said. “The lunch crowd is usually pretty thin. I think we’ll be okay.” He dusted his hands off and looked around. “What are you up to for the rest of the day?”

“Well,” the King said, “since we’ve come down this way, I was thinking we could—”

“Hang on a second. What’s this?” Scarlet interrupted, pulling a handful of what had appeared to be stray hash out of Squeaky Jim’s dustpan.

Squeaky Jim bent down to look at it. “Mostly mud,” he said.

“But what are these little red needles?” she asked. “And this shiny green thing?”

The King pulled a small magnifying glass from his kingly robe and leaned in to get a better look.

“Aha! I’ve seen those red needles before,” said the King. “Those come from the Carmine Pines.” He examined the shiny green thing for a minute. “But this,” he said, stroking his fluffy white beard, “this is something I’ve never come across in all my years of kinging about.”

“It looks like a scale,” Ruben said. “Like from a fish or a lizard!”

“Sweet corn muffins!” said the King. “You’re right! But it’s too big to be from any normal fish or lizard. Where could it have come from?”

“One thing at a time,” Scarlet said. “What are the Carmine Pines?”

“The Carmine Pines are a vast red forest on the eastern edge of the kingdom,” the King replied. “Only a few minutes’ walk from here, in fact.”

Scarlet turned the scale over in her palm. “Have you ever seen anything like this, Hank? Jim?”

“Never,” said Jim, and Hank shook his head.

Scarlet thought for a moment. “If this might be a clue to why the Hashery computer malfunctioned, we should investigate,” she said. “The sooner, the better!”

The King nodded vigorously. “This way,” he said. He turned to Big Hank and Squeaky Jim. “Thanks again for a lovely meal, guys!” he said. “I’ll be in again tomorrow!”

“Our pleasure, Your Majesty!” Hank smiled, and he and Squeaky Jim bowed.

Waving goodbye to Hank and Jim, the King, Ruben, and Scarlet stepped out of the Hashery and into the bright, late-mid-morning light.

“Right over there!” said the King, standing on tiptoe and pointing. The red treetops of the Carmine Pines were visible less than a mile away.

“Well, let’s get going,” Ruben said. “There’s still plenty of day left, and it’ll only take a few minutes.” With that, the three of them set out toward the forest.

“You know,” Scarlet said after a while, “I don’t think these Ruby malfunctions have been accidents at all.”

“Really?” asked the King.

“Think about it!” said Scarlet. “Your string goes missing, the Mysterious Pipe overflows, the Loop goes crazy, and the Hashery’s Computing Contraption goes haywire—all in the same day?”

“Well, the string bit might have been my fault,” the King said, sheepishly.

“Either way, I think Scarlet’s on to something,” Ruben said. “I think this is . . . SABOTAGE!”

“Great coats! Sabotage?” said the King. “Who would do such a thing?”

“I don’t know,” replied Scarlet, “but one way or another, we’ll find out!”

After a few more minutes of walking, the trio arrived at the edge of the Carmine Pines. Enormous pine trees towered over them, their red needles glinting in the sun.

image with no caption

Scarlet reached up with one hand and pulled down a handful of needles. She dug through her pocket with her other hand and pulled out the needles she’d found in Jim’s dustpan. The King examined both with his magnifying glass for nearly a minute.

“Absolutely the same,” he said at last. “These needles are from the Pines, all right!”

“You were right!” said Ruben. “But what do we do now that we’re here?”

“I imagine we’ll ask for a bit of help from someone who knows the area,” the King said.

“How?” asked Scarlet and Ruben together.

“With a Computing Contraption, of course!” said the King.

Scarlet looked around. “But we’re in the middle of the forest!” she said. “There are no Computing Contraptions between here and the Hashery.”

“Computing Contraptions are everywhere in the kingdom,” the King said. “You just have to know where to look.” He reached up and pulled on the lowest branch of a nearby tree, and a cleverly hidden Computing Contraption swung out from inside the tree’s trunk.

“Wow!” said Ruben. “Now what?”

“Well, I imagine we’ll need to use Ruby to figure out who lives here in the Pines,” the King said. “Even if we don’t find the owner of our shiny green scale, we might at least find someone to help us out.”

“Perfect!” said Scarlet. “So there’s a directory of people who live in the Kingdom stored in each Computing Contraption?”

“Well, yes,” said the King, rubbing his head. “But here’s the rub. I don’t know much about Ruby, but I do recall hearing once that there’s actually no built-in method to get a list of all those people.”

Ruben sat down on a flat rock. “No method!” he said. “How are we supposed to find someone to help us if Ruby doesn’t have a built-in method for it?”

Scarlet thought for a minute. “Well,” she said, “I think it’s possible to write our very own Ruby methods, but I’ve never actually seen it done before.”

“Write our own Ruby methods?” asked the King. “That would be marvelous! Are you sure it’s possible?”

“Of course it’s possible!” cried a nearby voice. The King and Scarlet both jumped, and Ruben nearly fell off his rock. They all turned in the direction of the voice to see, standing only a few yards away from them . . . a knight, with sword drawn!

“Agh!” Ruben shouted, and tried to hide behind his rock.

“What in the name of midnight snack marzipan is the meaning of this?” demanded the King.

The knight froze, then hastily pushed her visor up on her helmet.

“Your Majesty!” she cried, and bowed deeply. “A bajillion apologies! I didn’t recognize you with my visor down.” She quickly slid her sword back into its scabbard.

“A lady knight!” said Scarlet.

“No, just a knight,” said the King. “After all, if she were a man, you wouldn’t say, ‘A man knight,’ would you?”

“I suppose not,” admitted Scarlet.

“Who are you?” Ruben asked.

image with no caption

The knight stood tall and proudly put her hands on her hips. “I’m the Off-White Knight!” she replied.

“Off-white?” asked the King. “Your armor is more of an eggshell color, I think.”

“Maybe an ecru,” Scarlet said, squinting.

“I think that’s a large bird,” said the King.

“Enough tomfoolery!” said the knight. “I am the Off-White Knight, and now it’s time for you to DEFEND yourselves!”

“Agh!” shouted Ruben again, covering his head with his hands.

The knight tried to scratch her head, but ended up scratching the outside of her helmet. “Why are you cowering like that?” she asked.

“Aren’t you going to slay us?” Ruben asked.

The Off-White Knight laughed. “Heavens, no!” she said. “In fact, it’s my knightly duty to help anyone in the Carmine Pines who needs assistance, so I’ll show you how to write your own Ruby methods.”

“But it’s daytime,” said the King.

Ruben and Scarlet gave each other a knowing look.

Defining Your Own Methods

The Off-White Knight cleared her throat. “Yes. Well,” she said, “what I was trying to say was that you certainly can define your own Ruby methods. You simply need to use the special words def and end.” She walked up to the cleverly disguised Computing Contraption and began typing.

>> def simon_says(phrase)

>> return phrase

>> end

“You start by typing def, which is short for define, because you’re defining a brand-new method. Next, you type the name of your method, which is simon_says in this case. Then you put the parameters next, in between parentheses. For this method, we have just one parameter: phrase.”

“The what now?” asked the King, rubbing his head with both hands.

“The parameters,” said the Off-White Knight. “They’re sort of like placeholders or nicknames for the information you’ll give your method when you call it.”

“Let me get this straight,” said the King. “When you write out what a method does using def and end, that’s called defining the method.”

“That’s right,” said the knight.

“And when you actually use the method somewhere, that’s calling the method.”

“Indeed!” said the knight. “Sometimes we say invoke instead of call, but they mean exactly the same thing. You define a method so Ruby knows what it does, and you call the method when you want to use it. Calling a method looks like this,” she continued, and typed some more:

>> simon_says('Prepare for battle!')

=> "Prepare for battle!"

“I’m a bit fuzzy right now,” said the King.

“You’re a bit fuzzy all the time,” said the Off-White Knight, eyeing the King’s fluffy beard.

“Yes, yes,” said the King, “but I’m also still confused. Could you go over calling the method a bit?”

“Of course!” said the knight. “When we defined the simon_says method earlier, we just told Ruby what code to run whenever we use the name simon_says. We can then use that code by writing the method name and putting in our own bit of information—the string 'Prepare for battle!'—where we had the phrase parameter before. Like I said, phrase is just like a placeholder that sits between the parentheses until we’re ready to use the method with 'Prepare for battle!'.

“What about the parentheses around 'Prepare for battle!'?” Ruben asked. “I’ve seen Ruby methods get called without parentheses before.”

“You’re right!” said the knight. “The parentheses are optional; you usually use them when you define the method, but you can use them or skip them when you call the method. It’s all the same to Ruby!”

return Versus puts

“All right, I understand defining and calling now,” said the King. “But what’s this return business, and how is it different from puts? Don’t they both print things on the screen?”

“Aha!” said the Off-White Knight. “A lot of people find this very confusing, but I think I can show you the difference between return and puts with just a couple of examples.”

“Here we define a method called print_sum that prints the sum of two numbers with puts,” she said:

>> def print_sum(a, b)

>> puts a + b

>> end

“Next, we’ll define a second method that returns the sum.”

>> def return_sum(a, b)

>> return a + b

>> end

“Do you see the difference between the print_sum and return_sum methods we defined?” the knight asked. “One puts, the other returns.” Scarlet, Ruben, and the King all nodded.

“Perfect!” said the Off-White Knight. “Let’s see what that really means for what our Ruby code does. First, we’ll call our print_sum method.”

>> sum = print_sum(2, 3)

5

=> nil

>> sum

=> nil

“See that?” said the knight. “puts will print something on the screen for you—in this case, it added 2 and 3 and printed the result 5 to the screen—but it won’t do anything with the value of 5: it produces nil after doing the printing! When we check out the value of sum, we see that it’snil.”

“Now let’s call our return_sum method.” She typed some more:

>> sum = return_sum(2, 3)

=> 5

>> sum

=> 5

image with no caption

Now I understand,” said the King. “Printing something just makes that value appear on the screen, but returning it lets you store that value in a variable, as we did with sum.”

“You’ve got it!” said the knight. “A method is just like a little machine. Things go into it and things come out. The things that go into a method when you call it are its arguments, and the thing that comes out is its return value.

“If a method doesn’t have a specific return value, it returns nil. You know how you always see => nil when you puts or print something? That’s because although the puts and print methods write text on the screen, they don’t have a return value, so they return nil.”

“Hang on a moment,” said the King. “If a method can automatically return nil when it has no other value to return, why can’t we automatically return other values?”

Understanding Method Arguments

“We can!” said the Off-White Knight. “Whenever you’re in a method definition, Ruby automatically returns the last bit of Ruby code that gets run. If you want to save some typing, you can leave off the return keyword if the last thing in your method is the return value, and Ruby will automatically return it for you.”

“Awesome!” said Ruben “Anything that saves us some typing is good. Now, just to back up a second to the difference between parameters and arguments: parameters are the handy names you put between parentheses in your method definition to let your method know what kinds of information it will get, and the arguments are the information you actually give to your method when you call it,” Ruben said.

“Quite right!” said the Off-White Knight. “Hang on, let me give you another example.” She typed furiously into the Computing Contraption, narrating all the while. “Let’s define a method called add_things with the parameters thing_one and thing_two and return their sum. That’d look like this:

>> def add_things(thing_one, thing_two)

>> thing_one + thing_two

>> end

“Next, we’ll call the method with the arguments 3 and 7. The return value is 10.”

>> add_things(3, 7)

=> 10

“That’s great,” said Scarlet, “but what happens if you want to sometimes pass an argument to a method, and sometimes not? If you don’t pass the right number of arguments, Ruby throws an error!” She typed into the Computing Contraption:

>> def plus_one(number)

>> number + 1

>> end

>> plus_one 2

=> 3

>> plus_one()

ArgumentError: wrong number of arguments (0 for 1)

“Yeah!” said Ruben. “Here, Ruby’s saying that it got zero arguments, but it expected one.”

“Great point!” said the Off-White Knight. “In that case, you can use optional or default parameters. Those are special parameters that come with a placeholder value, and if you don’t give Ruby arguments for those parameters when you call the method, Ruby inserts the placeholders instead. Let me define a method like that for you,” she said, and began typing at the Computing Contraption once more:

>> def declare_name(name='The Off-White Knight!')

>> puts name

>> end

“See the equal sign?” she said. “That tells the method to use that string if it’s not told otherwise. Now, without any arguments, the method will use the default name,” she said. “Let’s try calling it!” She typed some more:

>> declare_name()

The Off-White Knight!

=> nil

“Wow!” said Ruben. “You didn’t pass any arguments at all, so the default one was used automatically.”

“That’s right,” said the knight. “And again, because Ruby is super flexible, you don’t even need the parentheses to show that you’re calling a method!” She typed even more:

>> declare_name

The Off-White Knight!

=> nil

“That looks a little too magical to me,” said the King. “If there were lots of code floating around, how would I immediately know the difference between a method with no parentheses and a plain old variable?”

“That’s a good point,” said the Off-White Knight. She tried to wipe the sweat from her brow, but accidentally knocked her visor down instead. “I often use the parentheses, because they make it clear I’m using a method and not something else, like a variable.”

“Now, let’s say you do want to use your own name,” she continued, struggling to push her visor back up. “You just pass it in—with or without parentheses—like this.” She typed a few more lines:

>> declare_name('Lady Scarlet the Bold!')

Lady Scarlet the Bold!

=> nil

>> declare_name 'Sir Ruben the Fearless!'

Sir Ruben the Fearless!

=> nil

“Whew!” said the Off-White Knight. “Let me take a break for just a second. My gauntlets are tired.”

What Is nil?

“Of course,” said the King. “I’m still a bit hung up on nil, though,” he said. “What is it?”

image with no caption

“I think I know the answer to that one,” Ruben said. “nil is Ruby’s way of saying ‘nothing at all.’ When Ruby wants to express the idea of ‘nothing’ or ‘no value,’ it uses nil.”

“Is nil true or false?” asked the King.

“Neither!” said Ruben. “It’s its very own thing. But it is one of two falsey values in Ruby—the other is false.”

“What do you mean by ‘falsey’?” asked the King.

“I mean that if you use nil in an if statement, it will be the opposite of true,” Ruben said. “This should look familiar.” He typed into the Computing Contraption:

>> if nil

>> puts "This text won't be printed!"

>> end

“Your code didn’t print anything on the screen!” said the King.

Ruben nodded. “That’s because Ruby will never treat if nil as a true condition. To Ruby, saying ‘if nothing’ and ‘if false’ are the same, so it will never run the code between if nil and end.” He thought for a moment. “Remember the if statement?” he asked.

The King nodded vigorously. “As if it were only yesterday!” he said.

“It was today,” said Ruben.

“Tomato, tomato,” said the King, pronouncing the word the same way both times. Ruben and Scarlet looked at each other and shrugged.

“Anyway,” said Ruben, “The if statement takes a bit of Ruby code and does one thing if that code is true and something else if it’s false. nil is always treated like false in if statements, so to make something happen if a value is nil, you might think you have to do this:

>> if !nil

>> puts "But I will get printed!"

>> end

But I will get printed!

=> nil

“But there’s a piece of built-in Ruby code we’ve already seen that means the same thing as ‘if not’: unless!” Ruben typed some more:

>> unless nil

>> puts "But I will get printed!"

>> end

But I will get printed!

=> nil

“unless has the exact same meaning as ‘if not.’ When we say ‘Stay up late if you’re not sleepy,’ that means the same thing as ‘Stay up late unless you’re sleepy,’” Ruben explained.

“I’ve seen this before!” said the King. “We use unless in Ruby anytime we’d otherwise use if and !.”

“Right!” said Ruben. “Both false and nil will behave the same way when used in an if or unless statement, but it’s important to remember that nil’s not the exact same thing as false.” He continued typing:

>> nil == false

=> false

“Did you see that => nil at the end of the unless example?” the Off-White Knight asked. “That’s what I was talking about. nil is the return value of puts. Check it out!” She reached over Ruben’s head and typed some more:

>> puts 'Prepare for nil!'

Prepare for nil!

=> nil

“One last thing about nil,” said the knight. “Not only is it not the same thing as false, it’s not the same thing as zero! Zero is a number; nil is simply nothing at all.”

“I think I’ve got it now,” said the King.

Splat Parameters

“Right,” said the knight. “Then we’re on to more method magic! I showed you how to make a method take an optional argument, but Ruby also lets you tell a method to take any number of arguments. Splat parameters are the way to tell a Ruby method, ‘Hey, I’m going to pass you a whole list of things to use. I don’t know how many, so just deal with whatever number I send!’” The knight flexed her fingers a few times. “They work like this,” she said, and began typing:

>> def declare_knights(*knights)

>> puts knights

>> end

>> declare_knights('Lady Scarlet', 'Sir Ruben', 'The Off-White

Knight')

Lady Scarlet

Sir Ruben

The Off-White Knight

=> nil

“You can think of the asterisk (*) in our first line as a little splat mark that tells the method to take the whole messy bucket of arguments, no matter how many, and do something with them,” the Off-White Knight said.

“I see the little splat next to the parameter name,” said the King, “but not in the method body and not when you call the method. Is the * only used when you define the method and only between the parentheses?”

“Exactly,” said the knight. “Ruby is very smart—you only have to tell it something once! As I mentioned,” the Off-White Knight continued, “Ruby realizes that the last thing that appears in your method body is probably the thing you want to return. So, as I mentioned earlier, if you want to save some typing, you can leave off the return keyword if the last thing in your method is the return value. Ruby does it automatically! That means that this:

>> def add(a, b)

>> return a + b

>> end

>> add(1, 3)

=> 4

is exactly the same as this!

>> def add(a, b)

>> a + b

>> end

>> add(1, 3)

=> 4

“Wonderful!” said Scarlet. “I’ll definitely remember that trick when writing my own methods.”

“And now,” said the Off-White Knight, pulling her sword out of its scabbard, “it’s time for you to YIELD!”

“Agh!” shouted Ruben, covering his head with his hands again.

Block Methods

The Off-White Knight struggled to get her sword back into its scabbard. “You really should do something about that cowering habit,” she said. “What I was saying is, you need to use the yield keyword when you write your own Ruby methods that take blocks.”

“Oh,” Ruben said, slowly putting his hands down again.

“Wait, you can write your own Ruby methods that take blocks?” Scarlet asked.

“Of course!” said the knight. “You’d write it like so,” she said, and typed in the Computing Contraption:

>> def my_block_method

>> yield

>> end

=> nil

“First,” said the knight, “we define a method, my_block_method, using def. Next, we use the yield keyword to tell the method to let the code inside the block run; when you call the method with a block, whatever happens in the block is what the method does! Let’s look at some examples.”

>> my_block_method { 1 + 1 }

=> 2

“Here, we’re calling my_block_method and passing in a block that just adds 1 + 1, so my_block_method returns 2. We can also do other things, like print text:

>> my_block_method { puts 'Hello from the block!' }

Hello from the block!

=> nil

“my_block_method lets the code in the block run, so it prints out Hello from the block! We see the nil because puts prints out text on the screen, but the value it returns is nil,” the knight explained.

“What’s a block, again?” the King asked.

“A block is just a bit of Ruby code between curly brackets or between do and end,” said the knight. “You’ve probably seen built-in methods like each that use blocks, but now you can create your own methods that use blocks!”

“That’s amazing!” said Scarlet. “But can you use splat parameters and blocks together?”

“You can!” said the knight. “You can pass regular, default, and splat arguments to any method you write, and they can be in any order.”

The knight cracked her knuckles and typed into the Computing Contraption, explaining as she went along. “Let’s build a little something we can use to quickly and easily introduce ourselves,” she said. “After all, we knights are always having to go around introducing ourselves as we sally forth into a new town.”

>> def all_about_me(name, age=100, *pets)

>> puts "My name is #{name}"

>> puts "I'm #{age} years old"

>> if block_given?

>> yield pets

>> else

>> puts pets

>> end

>> end

=> nil

“We’re not done yet,” said the knight, “but let’s go over this. First, I defined the all_about_me method to take three parameters. We see a regular old name parameter and an age parameter, which defaults to 100 if no age is passed in when the method is called.”

“But you could have written the age parameter with its default first, then the name one,” Ruben said.

“You got it,” said the knight. “Finally, the *pets splat parameter! That can come in any order with respect to the regular or default parameters, but we happened to put it at the end.”

“I get that part,” said the King, “but what’s this block_given? business?”

“That’s a built-in Ruby method,” said the knight. “It returns true if the method was passed a block as an argument and false otherwise. I wrote the all_about_me method so it yields to the block if there is one, sending the list of pets to the block; otherwise, it just uses puts to print out the pets. Don’t worry if block_given? doesn’t make perfect sense now—we’ll be seeing more of it later on.”

“Why is it yield pets and not just yield?” Scarlet asked.

“An excellent question,” said the knight. “Earlier, we just wanted to let the block handle everything that was passed to our method, so we simply typed yield. Now, though, we want our block to care only about pets, so we specifically give only our list of pets to the block.”

The knight’s fingers moved again across the Computing Contraption, giving their newly defined method a try.

>> all_about_me('Ruben', 12, 'Smalls', 'Chucky Jim')

My name is Ruben.

I'm 12 years old.

Smalls

Chucky Jim

=> nil

“That’s me!” said Ruben. “That’s amazing. What else can we do?”

“Well,” said the Off-White Knight, “We can use that block I mentioned earlier! Look what happens if we pass a block to our method, then refer to the pets we pass in with pets:

>> all_about_me('Ruben', 12, 'Smalls', 'Chucky Jim') { |pets| puts

pets.join(' and ') }

My name is Ruben.

I'm 12 years old.

Smalls and Chucky Jim

=> nil

“This looks a lot like the last example,” said Scarlet. “But the block is pretty tricky. What’s it doing?”

“I’ll walk you through it! First, { |pets| puts pets} would simply tell Ruby: ‘Hey, block! I’m going to pass you a variable, pets, and you should print it out.’”

“But then all_about_me would just print out the array elements, and it wouldn’t look very nice,” Scarlet said.

“Exactly!” said the knight. “So I’m also using a built-in Ruby method, join. Ruby array elements can be joined to make strings, so I’m using join to turn the array of pets into a string with ' and ' in the middle.”

“Could you show us another example?” Ruben asked.

“Sure,” said the knight. “Here’s one where we can use join to turn an array of numbers into a string with 'plus' between each number:

>> [1, 2, 3].join(' plus ')

=> "1 plus 2 plus 3"

“There’s always something new to discover in Ruby,” marveled the King.

Into the Dagron’s Lair

“Speaking of discoveries,” said Scarlet, “that reminds me!” She rummaged around in her pockets. “Have you ever seen anything like this before?” She held out the glittering green scale for the Off-White Knight to examine.

“Great googly moogly!” said the Off-White Knight. “That scale looks like it belongs to the Dagron!”

“You mean the dragon,” Ruben offered.

“No, the Dagron,” said the Off-White Knight. “That’s her name. Though she is a dragon.”

“A lady dragon!” said Ruben.

“No, just a dragon,” said the Off-White Knight. “If she were a man, would you call her a man dragon?”

“I guess not,” admitted Ruben. He looked around nervously. “But there’s really a dragon in the Carmine Pines?”

“Not to worry,” said the knight. “The Dagron is a very powerful dragon, but she’s also wise and well mannered. In fact, I’m surprised you found one of her scales anywhere trouble’s been brewing. That doesn’t sound like the Dagron I know.”

“Well, it sounds like we’d best find her and ask what’s going on,” said the King. “Lead the way, madam knight!”

“To the Dagron!” said the Off-White Knight, flipping her visor down over her eyes. “This way!” The knight set off deeper into the forest, and the King, Scarlet, and Ruben followed.

After walking for a few minutes, they began to hear a low, rhythmic whooshing sound, like someone squeezing bellows on a fire.

“What’s that?” Ruben whispered.

“The Dagron!” whispered the knight. “Here she is!” And before they knew it, they found themselves in front of an enormous dragon curled up in a shining green circle, asleep.

image with no caption

“Dagron!” the knight called, pushing her visor up on her helmet.

The Dagron didn’t open her eyes. “Yes?” she boomed, a thin plume of smoke rising from her right nostril.

“I’ve brought some guests to see you, including the King!”

The Dagron’s eyes flashed open, focusing immediately on the four of them. The Dagron unfurled herself and reared up to her full height; her head nearly reached the tops of the pines around her.

“Your Majesty!” said the Dagron, and she bowed so low that her head nearly brushed the earth.

“Madame Dagron,” said the King. “We’ve come with a somewhat . . . unusual question.” The King nodded toward Scarlet. “Does this belong to you?”

Scarlet pulled the scale from her pocket and held it out to the Dagron. The Dagron stared at it for a few seconds, then shook her head slowly.

“I don’t think that’s one of mine,” said the Dagron, “but I do have a great many scales. If you’d like, you can check to see if I’m missing one.”

The group spent almost an hour examining the Dagron, looking for a loose or missing scale. Scarlet and Ruben searched high and low. The Off-White Knight quested mightily. The King took a short nap beneath a tall red pine.

“Well, there’s no doubt about it,” Scarlet finally said, holding the mystery scale near the tip of the Dagron’s tail. “This is definitely not one of the Dagron’s.” She put the scale in her pocket and sat glumly next to Ruben on a rock.

“Though I’m pleased not to be a suspect in these strange goings-on,” said the Dagron, “I am sorry to disappoint you.” She thought for a moment. “While I’m not certain I can help, I may know someone who can.”

Scarlet perked up. “Who?” she asked.

“Wherefore the Wand’ring Minstrel,” said the Dagron. “He frolics and sings all throughout the Carmine Pines and has been almost everywhere in the kingdom. If anything strange is going on, I’m sure he’d know about it.”

Ruben jumped off his rock. “Can you take us to him?” he asked.

“Certainly,” said the Dagron. “It may take us a while to find him, though.”

Scarlet stood and dusted herself off. “Actually, I’ll bet we can find him pretty quickly,” she said. “Now that we know how to define our own Ruby methods, I might know just the thing!”

You Know This!

Between defining your own methods, creating your own methods that use blocks, and learning about things like splat and default arguments, your head’s probably feeling pretty full! Let’s take some time to review what we talked about in this chapter.

First, you learned how to write your own methods. We start our method definition with def, followed by the name of the method and then a list of parameters between parentheses. Finally, we type whatever code we want our method to perform and then finish it all up with end, like so:

>> def multiply_by_three(number)

>> number * 3

>> end

>> multiply_by_three(2)

=> 6

You also learned that methods can have default or optional parameters. If we provide an argument to a method that takes an optional parameter, the method will use that argument; otherwise, it’ll use whatever its default is:

>> def multiply_by_three(number=2)

>> number * 3

>> end

>> multiply_by_three

=> 6

>> multiply_by_three 3

=> 9

If we want a method that takes any number of arguments, we can use splat parameters by putting an asterisk (*) before our parameter name:

>> def print_all_the_names(*names)

>> puts names

>> end

>> print_all_the_names('Larry', 'Curly', 'Moe')

Larry

Curly

Moe

=> nil

Speaking of nil, you learned that methods that don’t have an explicit return value will return nil, which is Ruby’s way of saying “nothing at all.” Remember, returning a value is different from just printing it on the screen!

>> puts 'Beware the Dagron!'

Beware the Dagron!

=> nil

In fact, when it comes to return values, it’s more common to leave off the return and let Ruby automatically return the result of the last bit of code it runs. So while you can write this:

>> def just_return_two

>> return 2

>> end

>> just_return_two

=> 2

It’s much better Ruby style to write this:

>> def also_returns_two

>> 2

>> end

>> also_returns_two

=> 2

Finally, we saw that if we want to define a method that takes a block, we just need to use the handy yield keyword. We can yield without parameters to give control over to the block, or we can pass parameters in order to give the block arguments to work with.

>> def block_party

>> yield

>> end

>> block_party { puts 'Hello from the block!' }

Hello from the block!

=> nil

>> def block_party_part_two(name)

>> yield name

>> end

>> block_party_part_two('Haldo') { |name| puts "This is #{name}'s

party!" }

This is Haldo's party!

=> nil

You learned a lot in this chapter, but keep in mind: if you’re ever curious about what a method does or what arguments it expects, you can always look up the Ruby documentation at http://ruby-doc.org/. Just make sure to ask your local adult before going online!

Speaking of looking up new things, we’ll be covering a bit of new Ruby code in the next chapter—specifically, how to organize, create, and control our very own Ruby objects.