Follow the WEBrick Road - Ruby Wizardry: An Introduction to Programming for Kids (2014)

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

Chapter 13. Follow the WEBrick Road

Ruby and the Internet

The King and Queen burst through the Refactory exit and into the bright late-afternoon sunshine, Ruben and Scarlet following hot on their heels. Ahead of them, the WEBrick road stretched far away, its dark red bricks glowing softly. In the distance, they could make out the hunched shapes of the four mysterious villains retreating, and farther still, the wall that marked the outer edge of the kingdom.

“They’re so fast!” Ruben gasped, his hands on his knees. “We’ll never be able to catch them!”

“Never say never,” Rusty said, jogging up behind them. “There must be something we can do.”

The Queen turned to him. “Is there any way to shut down the WEBrick road?” she asked.

image with no caption

Rusty thought for a moment. “I’m not sure,” he said, “but I have an idea.” He flipped up all the pages of his clipboard and pulled out a thin piece of metal with a familiar-looking screen. “This is my portable Computing Contraption,” he said. “My workers and I will go on ahead and try to catch these snakes. In the meantime, if there’s anything you can do to shut down the road and keep them from escaping, you can do it on this little computer.”

“Right!” said Scarlet, taking the hand-held computer from the Foreman. Rusty gave her a wink, then motioned to the men and women of the Refactory who were rapidly pouring out of the exit. “This way, everyone! Let’s try to head these villains off! Move, move, move!”

As the Refactory workers ran down the deep red road, the King, the Queen, Scarlet, and Ruben huddled around the Foreman’s portable Computing Contraption.

“Okay, first things first,” said Scarlet. “How can we shut down the road?”

The King tugged on his fluffy white beard. “It seems to me,” he said, “that we should first check to be sure the road is working properly! If it’s already off for some reason, we can join Rusty’s team up ahead and apprehend these goons.”

Scarlet and Ruben looked at each other. “That’s . . . actually a great idea,” Ruben said. “How do we test to see if the road is open?”

“Well,” said the King, “the WEBrick road, like all things in the kingdom, runs on Ruby, and it’s the main connection between the kingdom and the rest of the world. If we can use Ruby to check whether we can get information from outside the kingdom, we’ll know if the road is working.”

“That’s it!” said Ruben. “If we can connect to the Internet with Ruby, then we’ll know the road is open!”

“But how do we do that?” said Scarlet. “I feel like I know Ruby pretty well now, but I don’t even know where to begin with connecting to the Internet.”

“I think I know a way,” said the Queen. “You see, connecting to the Internet is just like connecting to a file—you just have to tell Ruby the right way to do it! May I?” she asked. Scarlet nodded and handed the Queen the portable Computing Contraption. The Queen began to type.

“Remember how we could write our code in separate Ruby files, then use require to pull one script’s code into another?” the Queen asked. Scarlet and Ruben nodded. “Well,” the Queen continued, “it turns out there are little bundles of files that come with Ruby that we can require, too!”

“There are?” asked the King, incredulous. “Absolutely!” said the Queen. “You can think of these bundles of files as tiny libraries of code that we can use in our own projects. They’re called gems.”

“That’s right! I think I’ve heard of Ruby gems before,” Ruben said. “Is there a gem for connecting to the Internet?”

Using the open-uri Ruby Gem

The Queen nodded. “The open-uri gem,” she said. “It lets your Ruby code open Internet sites the same way it can open files! Once we require it in our IRB session, we’ll be able to do all sorts of wonderful things.” She typed into the Computing Contraption:

>> require 'open-uri'

=> true

She handed the little machine back to Scarlet. “Loaded up and ready to go!” she said.

Scarlet looked at the screen. “Don’t I need './open-uri', not just 'open-uri'?” she asked.

“Not for gems!” said the Queen. “That’s true for files you create, but if you’re requiring a gem, you can just type the name as a string. One of the many things Ruby does for you is keep track of where gems are installed on your computer. Since it already knows where to find them, you don’t need to look in the current directory with ./. Just type the name of the gem, and Ruby does the rest.”

“Perfect!” said Scarlet. “Now we just need a website to test whether the WEBrick road is working.”

“Aha!” said the King, raising a finger in the air. “We can test it with my favorite website!”

“Which one is that?” asked Scarlet, poised to type into the keyboard.

Example.com!” the King said, beaming. The Queen rolled her eyes.

“It’s as good as any,” Scarlet admitted, and she typed into the tiny Computing Contraption.

NOTE

You’ll need to be connected to the Internet for this code to work! Go ahead and grab your local adult if you need help connecting to the Internet.

>> site = open('http://www.example.com')

=> #<StringIO:0x000001032de2f0>

“First,” Scarlet said, “we’ve used the open method to tell Ruby to create an object based on the website of the URL we entered. Then we can just use the .read method as we did on a regular text file, and that will give us the contents of the site at www.example.com!”

>> site.read

=> "<!doctype html>...

The screen quickly filled with code from the example.com website.

“It’s working!” Scarlet said. “The WEBrick road must be turned on. Now we just need to find a way to shut it down!”

Ruben thought for a moment. “Hey, wait,” he said, “does the kingdom request and send information through the WEBrick road?”

“It does,” said the King.

“Does that mean there’s some kind of web server running?” Ruben asked.

The Queen snapped her fingers. “Ruben, you’re a genius!” she said. Ruben blushed slightly. The Queen turned to Scarlet. “Not only is there a web server running, but it’s a WEBrick web server.” She began talking quickly and gesturing excitedly. “The WEBrick server is a special piece of Ruby code that sends information out of the kingdom. You see, when you visit a website, you’re asking a web server—that is, a computer somewhere on the Internet—for information. Well, when people on the Internet want information about our kingdom, our very own WEBrick web server sends it!”

NOTE

The WEBrick server isn’t something that exists only in the kingdom—that’s the real name of the Ruby web server you’re using right on your own computer!

“And if that web server is turned off . . .” Ruben began. “. . . then nothing and no one can get out of the kingdom!” Scarlet finished.

“Now we just need to figure out how to find the server to shut it down,” Ruben said.

“Well,” said the King, kicking at a bit of dust, “I actually might be able to help with that. You see, I lose things so frequently that I’ve gotten to know the Computing Contraption’s search function very well.”

“Perfect!” said Scarlet. “What do we think the file is called?”

Investigating the Kingdom’s Web Server

“Well, you might want to search for WEBrick or server,” the King said. “That’s what I’d do, at any rate.”

Scarlet nodded and pressed a few keys, searching for the file. She squinted, shook her head, typed, sighed, thought, and typed some more.

“I think I’ve got it!” she finally said. “I found a file called server.rb.”

“Open it, open it!” said Ruben, standing on tiptoe to see the screen better.

Scarlet opened the server.rb file, and this is what they saw:

require 'webrick'

include WEBrick

server = HTTPServer.new(

:Port => 3000,

:DocumentRoot => Dir.pwd

)

trap('INT') { server.shutdown }

server.start

“Let’s see,” said Scarlet. “It looks like the first two lines require the webrick gem and include the WEBrick module.”

“That looks right to me,” said Ruben. “Then it looks like the next few lines create a new WEBrick server. I’m not sure what the port is for, but it’s set to the number 3000. What does the Dir.pwd part mean?”

“I think I know,” said the Queen. “Just like Ruby uses the File class for methods that work on files, it uses the Dir class for methods that work on directories, which is just a fancy way of saying folders.” The Queen pointed to the screen. “The pwd method returns the present working directory, so Dir.pwd is just Ruby’s way of saying ‘this folder right here.’ The web server is running, and it’s sending information out of this folder!”

“Okay!” said Scarlet. “We’ve just got to shut it down, and I think I see a clue. The trap('INT') { server.shutdown } line—what does that do?”

The Queen studied the screen for a minute. “If I remember correctly, that’s Ruby’s way of saying that when it gets an interrupt signal, it will shut down the server!”

“An interrupt signal?” Ruben asked. “Does that mean we have to tell the server to quit running?”

“Exactly,” said the Queen. “But how?”

“Hold down the CTRL key and the C key at the same time!” the King suddenly. Everyone turned to look at him. “Just do it!” he urged, waving his hands in the air. “We haven’t a moment to lose!” Scarlet nodded and immediately pressed the keys, and this is what she saw:

INFO going to shutdown ...

INFO WEBrick::HTTPServer#start done.

“We did it! We did it!” Scarlet and Ruben jumped up and down and hugged each other.

The Queen turned to the King, smiling. “How on Earth did you know how to do that?” she asked him.

The King smiled sheepishly. “Well, I manage to break my Computing Contraption so often, I’ve learned to use CTRL-C to stop programs!” They all burst into laughter.

“Now that the server is shut down,” Scarlet said, “nothing and no one can get out of the kingdom! Quick, let’s get down the WEBrick road and see if we stopped the bad guys in time!”

The four of them hurried down the bright red path, hoping against hope that they’d closed the WEBrick road in time. In the distance, they could see the huge group of Refactory workers milling around. As they got closer, they could start to pick out individual workers, then faces. Soon they were close enough to see that Rusty was frantically waving them over, and just beyond him in the center of the group were the four hooded hooligans!

“Great coats! Sweet breakfast gravy! Glorious corn muffins! We’ve got them!” cried the King, nearly weeping with joy.

As they ran up to the group, the Foreman turned to them, beaming. “Your Majesty! Your Highness!” he said, addressing the King and Queen in turn. “I don’t know how you did it, but you shut down the WEBrick road long enough for us to catch these villains! They were pulling on the gates to the kingdom wall, trying to escape, when we cornered them here.” He crossed his arms and smiled, his entire big bushy beard rising on his face. “I’m pleased to formally hand them over to you.”

“Thank you, Rusty,” said the Queen. The King and Queen moved into the center of the group, where two Refactory workers each held one of the four mysterious figures. Ruben and Scarlet followed close behind.

“You scoundrels have been creating utter pandemonium in our kingdom!” the King said.

“And depriving all the citizens in the kingdom of their Purple Panda-monium Parade,” the Queen said, frowning.

“Yes, precisely,” said the King. “And we’ve had enough of it! It’s time for you to reveal who you really are.” The King nodded to the Refactory workers. Each placed a hand on either side of each prankster’s hood.

“On my count. One . . . two . . . two and a half . . . three!” cried the King, and the workers yanked back the hoods. The crowd gasped. Standing before them, flicking their tongues and hissing, were four enormous snakes!

image with no caption

“Literal snakes!” said Rusty. “How about that?”

“Pythonssss, actually,” hissed the snake nearest to Rusty.

“Sweet hibbeldy-jibbeldy! A talking snake!” said the King, hiding behind a particularly brawny Refactory worker.

“The name issss Terry,” the snake said. “Terry One, actually.” She gestured with her head to the snake next to her. “That’s John,” she said. “Then Terry Two, then Graham.”

“Pleassssed to meet you,” said John.

“Well, we’re certainly not pleased to meet you,” said the King, recovering his courage. “What in the name of the Carmine Pines did you think you all were doing, causing such trouble?” He started counting on his fingers. “Stealing my string! Clogging the Mysterious Pipe! Looping up the Loop! Crashing the Hashery’s Computing Contraption! Hacking into the Queen’s machine! De-purpling the pandas! The list goes on and on!”

Graham looked around uneasily. “Your ssssstring? We didn’t steal your ssstring!” he said.

The King threw up his hands. “Okay, fine, maybe that was me,” he said, “but the rest was all your doing. I demand an explanation!”

Terry Two lowered her head; Ruben and Scarlet couldn’t tell if she was angry or sad. “It’s becaussse everyone was all about Ruby, Ruby, Ruby!” she said. “No one wanted to use Python anymore.”

“Python?” asked Ruben.

“You ssssee?” said Terry Two, nodding her head at Ruben. “The boy’s never even heard of Python!”

“What is it?” Ruben asked, inching forward.

Terry Two sighed. “A programming language, very much like Ruby,” she said.

“But better,” John piped up.

“Oh, much better,” Terry One chimed in.

“But no one in the kingdom uses it,” Terry Two continued.

“We thought if we got people thinking that sssssomething was wrong with Ruby, they might make the sssswitch.”

Scarlet stepped closer to the pythons, angry. “You should have tried to show how good a language Python is, not try to make people think there’s something wrong with Ruby!” she scolded.

John shook his head sadly. “No one would lissssssten,” he said, “so we thought our besssst chance would be to attract attention, even if it had to be negative.” No one could be quite sure, but it looked like the enormous snake had tears in his eyes.

The King’s expression softened a bit. “You all know Python?” he asked.

The pythons looked at each other, clearly confused. They slowly nodded.

“Tell me about it,” said the King.

“It’s quite a wonderful language,” said Graham. “It has sssstrings and numbers and Booleans.”

“Arrays, too!” added Terry One.

“Objects and methods and classsses,” said John, “and you can write programs that do anything you like.”

The King nodded, walking in a small circle. “It seems to me,” he said, “that Ruby and Python aren’t all that different, then.”

The pythons were silent for a moment. “Perhapssss not,” John said, finally. “But if that’ssss so, why not use Python instead of Ruby?”

“I suppose my question,” the King said, “is why do you need to choose? Why not write whichever you prefer?” Terry One opened her mouth to speak, but the King continued. “In fact,” he said, “what if I told you that it’s possible to write Ruby that turns into Python?”

There was total silence. Ruben, Scarlet, and the Queen shot one another amazed looks.

“You see,” said the King, “I’ve never been a very good programmer. Programming has never come easily to me. So I spend much of my time practicing and reading articles and sample code, trying to become better.” He reached into his robe and pulled out a small scroll. “During my research, I discovered a truly amazing bit of code that can transform Ruby code into instructions that Python can understand. You can write Ruby, and Python programs will come out! Isn’t that amazing?” he asked, becoming excited. “You can write any language you want any way you want, and you can still tell stories to a computer that will make it do anything you like. That’s the beauty of programming!”

The pythons didn’t say anything for a moment. Finally, Terry One spoke up. “I . . . hadn’t thought of it that way before,” she said.

“I suppose what I’m trying to say,” said the King, “is that all curiosity, all honest desire to learn, all sharing and teaching, is always welcome in this kingdom. Yes, we happen to use Ruby to run our day-to-day lives. Yes, it’s the language that many of our citizens know and prefer and eventhink in. But that doesn’t make it the only way, and it certainly doesn’t mean we think there’s nothing to learn from Python!”

Rusty cupped his hands around his mouth. “Hear, hear!” he said, and the entire crowd burst into applause.

“What do you say?” the King asked gently, approaching the four pythons. “Would you like to help us learn a bit about Python, and we can teach you some Ruby?”

The pythons exchanged glances, then began to nod.

“We’re ssssso terribly ssssorry,” Graham said. “We were just ssssad and frusssstrated, and we didn’t know how to tell everyone how we felt.”

“We hope we didn’t wreck anything too badly,” Terry Two said.

“We’ll help repair anything we broke,” Terry One added.

“I tried the hash at Hank’ssss Hashery,” John said. “It was the mosssst amazing food I’ve ever tasted. I’d help fix a hundred Ruby programs if I could eat there again!”

“Then it’s settled!” the King said. He looked at the Queen, who smiled and nodded. He returned his gaze to the four pythons. “By the power vested in me by the many citizens of my kingdom, you are hereby officially pardoned of all wrongdoing!” He leaned forward slightly. “And if you’d like to come back to the palace for some cake and tea, that would be fine, too.”

The pythons nodded eagerly, overjoyed. “That would be sssssplendid,” said Terry One. “Thank you sssso much!”

The King held his arms over his head. “Everyone back to the Royal Palace!” he cried. “Cake and tea for everyone!”

A massive cheer went up in the crowd. The Refactory workers who had been holding the pythons released them, and the group swept the King, the Queen, Scarlet, and Ruben up onto their shoulders.

“You really saved the day, Your Kingliness!” Scarlet said to the King. He dismissed the compliment with a wave of his hand.

“You kids did all the saving!” he said. “Without you, we’d never have solved this mystery and brought peace and prosperity back to the kingdom.”

“Let’s say we all had a piece of the pie,” said the Queen. “And speaking of! Let’s add a little pie to this cake-and-tea party.”

“Let’s!” said the King, who had been patting the pockets of his robe for the last several seconds. “Oh, turnips,” he said. “Now where did I put my string?”

image with no caption

Beyond the Kingdom Walls

Holy cannoli! Pythons! I wouldn’t have seen that coming 42 miles away. I’ve still got so many questions! How did they sneak into the kingdom? What cool Python tricks do they know that a Ruby programmer like me could learn? And how did they manage to work a Key-a-ma-Jigger with no hands?

While I ponder these and other great mysteries, feel free to get in a little more practice with the WEBrick web server. Go ahead and create a new file called web_server.rb and type in the following code.

web_server.rb

require 'webrick'

include WEBrick

server = HTTPServer.new(Port: 3000)

server.mount_proc '/' do |request, response|

response.body = 'Your Ruby adventure is just beginning!'

end

trap('INT') { server.shutdown }

server.start

This code’s a bit different from the last version you saw, but there’s nothing here you haven’t seen! The only tricky bit is the mount_proc method, which is built into WEBrick. This tells the server how to respond to certain requests; in this case, if you go to the / URL on your computer, you should see the message assigned to response.body. Your computer’s built-in website is http://localhost/.

As usual, you can run your finished script by typing ruby web_server.rb in the terminal. Once you’ve started your script, you should see some numbers and text, like this:

INFO WEBrick 1.3.1

INFO WEBrick::HTTPServer#start: pid=78115 port=3000

(Your numbers will be slightly different, but the words should be pretty similar.) When you see the text appear, your web server is up and running! Open your favorite web browser (such as Chrome, Firefox, Internet Explorer, or Safari) and go to http://localhost:3000/. If everything’s working right, you should see Your Ruby adventure is just beginning! in the browser window. Crazy, right? Your first website has just been born! (I’m gonna name her Marigold.) When you’re done using your server, hold down CTRL-C in the terminal where WEBrick is running to shut it down.

This web server is a pretty simple affair, and if I know you, you’re already thinking of ways to make it better. Well, don’t hold back! Feel free to play with the code in the web_server.rb file. (You’ll need to use CTRL-C to shut down the server and restart it each time you make changes in order to see them.) For example, you could start just by changing the response.body string, then move on to playing with the port number or adding more mount_procs.

Here’s a hint: What if you add the following code to your web_server.rb file, then go to http://localhost:3000/favorite_vegetable?

server.mount_proc '/favorite_vegetable' do |request, response|

response.body = 'Certainly not yams!'

end

If you want to see the gems that people all over the world have made available, you can visit the RubyGems website at http://rubygems.org/. For just about any task, someone has probably created a gem to do it, so you should always stop by RubyGems. Take your time to read through the information on the site, and you’ll be able to download other people’s gems and use them in no time!

Speaking of sharing code, that magical little program that can convert Ruby to Python really does exist! It was written by a programmer named why the lucky stiff and can be found on GitHub, a website where people share the code they write with people all across the planet. You can find the GitHub website at https://github.com/ and the Ruby-to-Python project—called unholy—at https://github.com/whymirror/unholy/. (The code is very advanced, but if you keep at it, I think you’ll start to get it. I’ve yet to meet a brighter bulb!)

You Know This!

We took some of the code and concepts you already knew a few steps further in this chapter, so let’s take a second to make sure it all made sense.

You learned that we can use Ruby to get information about websites on the Internet by using the open-uri gem:

>> require 'open-uri'

=> true

>> site = open('http://www.example.com')

=> #<StringIO:0x000001032de2f0>

>> site.read

=> "<!doctype html>...

A gem is just a set of files that someone else created to make writing your Ruby programs easier. We can require gems into our programs just as we can require files we wrote ourselves, only we need to put a ./ before our filenames, and for gems, we can just write the name as a string after the require method call.

Feel free to try this code with other websites! Just be sure to get permission first, and be careful—some websites send back a lot of code, and it may fill up your terminal window.

You also saw that we don’t have to settle for just requesting information; we can serve it to visitors using web servers like WEBrick:

require 'webrick'

include WEBrick

server = HTTPServer.new(:Port => 3000)

server.mount_proc '/' do |request, response|

response.body = 'WEBrick is online and running fine!'

end

trap('INT') { server.shutdown }

server.start

You learned that we can modify web server code to write simple messages, that we can see the changes in our code by stopping and restarting the server, and that CTRL-C will let us stop our server (once we get it running) by typing ruby server_file_name.rb or calling load 'server_file_name.rb' from inside IRB.

Finally, we talked a little bit about using gems written by other people by visiting the RubyGems website (http://rubygems.org/) and reading and sharing code all over the world through the GitHub site (https://github.com/). If you want to set up accounts on these sites, grab your nearest adult and ask!

Our story may be over, gentle reader, but that doesn’t mean I’m quite done blabbering yet. We covered a lot of Ruby magic in the last several hundred pages, and I’d be a terrible teacher, writer, and programmer if I just said, “Welp, see ya!” and left it at that. Take a deep breath, turn the page, and let’s spend just a few more sentences going over all the crazy, amazing, wonderful stuff we’ve learned.