The blue window above is a Ruby prompt. Type a line of Ruby code, hit Enter and watch it run!
For example, try typing some math. Like: 2 + 6
Good! You did a bit of math. See how the answer popped out?
Ruby recognizes numbers and mathematic symbols. You could try some other math like:
4 * 105 - 1240 / 4Sure, computers are handy and fast for math. Let's move on. Want to see your name reversed?
Type your first name in quotes like this: "Jimmy"
Perfect, you've formed a string from the letters of your name. A string is a set of characters the computer can process.
Imagine the letters are on a string of laundry line and the quotes are clothespins holding the ends. The quotes mark the beginning and end.
To reverse your name, type: "Jimmy".reverse (Don't forget the dot!)
You have used the reverse method on your name! By enclosing your name in
quotes, you made a string. Then you called the reverse method, which works on strings to flip
all the letters backwards.
Now, let's see how many letters are in your name: "Jimmy".length
Now, I'm sure by now you're wondering what any of this is good for. Well, I'm sure you've been to a website that screamed, Hey, your password is too short! See, some programs use this simple code.
Watch this. Let's multiply your name by 5. "Jimmy" * 5
Let's look at what you've learned in the first minute.
reverse
and symbolic methods like * (the multiplication method.) Methods are action!This is the essence of your learning. Taking simple things, toying with them and turning them into new things. Feeling comfortable yet? I promise you are.
Okay, let's do something uncomfortable. Try reversing a number: 40.reverse
You can't reverse the number forty. I guess you can hold your monitor up to the
mirror, but reversing a number just doesn't make sense. Ruby has tossed an error
message. Ruby is telling you there is no method reverse for numbers.
Maybe if you turn it into a string: 40.to_s.reverse.
And numbers are different from strings. While you can use methods on any object in Ruby, some methods only work on certain types of things. But you can always convert between different types using Ruby's "to" methods.
What are arrays?! They are lists. Type in a pair of brackets: [].
Great, that's an empty list. Lists store things in order. Like standing in line for popcorn. You are behind someone and you wouldn't dream of pushing them aside, right? And the guy behind you, you've got a close eye on him, right?
Here's a list for you. Lottery numbers: [12, 47, 35].
A list of lottery numbers. Which one is the highest?
Try: [12, 47, 35].max.
Good, good. But it's annoying to have to retype that list, isn't it?
Let's save our numbers inside a ticket like so: ticket = [12, 47, 35]
Now, type: ticket
Fantastic! You've hung on to your lotto numbers, tucking them away inside a
variable called ticket.
Let's put your lotto numbers in order, how about? Use: ticket.sort!
You had a list. You sorted the list. The ticket variable is now changed.
Did you notice that the sort! method has a big, bright exclamation at the end?
A lot of times Ruby methods shout like that if they alter the variable for good. It's nothin
special, just a mark.
Now, look how your second minute went:
ticket = [14, 37, 18].In all there are eight lessons. You are two-eighths of the way there! This is simple stuff, don't you think? Good stuff up ahead.
Let's change directions for a moment. I've stuffed a bit of poetry for you in
a certain variable. Take a look. Type print poem
Look, it's okay. You don't have to like it. Hack it up, be my guest.
Instead of toast, go for a melon or something. Try this: poem['toast'] = 'honeydew'
And then type print poem by itself to see the new poem.
The square brackets you just used are very common in Ruby. Remember, you typed: poem['toast'] = 'honeydew'. That box with the word toast has a square bracket on each side, see?
The two brackets are like sights used to line up a target. Exactly. These brackets mean, "I am looking for ____." Ready, aim. Here you're looking for toast and swapping it out with fruit.
Here's a question: what happens when we reverse this whole poem? poem.reverse
Okay, sure. So the whole poem's been turned backwards, letter-by-letter. I really want to just reverse the lines, though. Move the last line up to first and the first line down to last. Backwards, but not that backwards.
Here's how: poem.to_a.reverse
So what do you see? What happened there? You typed poem.to_a.reverse and what happened?
Two things happened. You turned the poem into a list using to_a. (To array.) When Ruby turns a string into an array, its breaks the whole thing up at each line break. So you end up getting each line of the poem.
Then, you reversed that list. You had each line. You reversed them. That's it.
Let's tack one more method on the end there: print poem.to_a.reverse.join
Good show, my friend! The join method took that list of reversed lines and put them
together into a string. (Sure, you could have also just used to_s.)
Review time.
poem.include? "my hand"poem.to_a.reverse.joinAt this point, you may want to tinker with the poem a bit more. A complete list of all
the String methods is here. Go ahead and try a few (such as poem.downcase or poem.delete.)
When you're ready to move on, type: books = {}
You've made an empty hash. (Also known as: an empty dictionary.)
We're going to stuff some miniature book reviews in this hash. Here's our rating system:
:splendid → a masterpiece.:quite_good → enjoyed, sure, yes.:mediocre → equal parts great and terrible.:quite_not_good → notably bad.:abyssmal → steaming wreck.To rate a book, put the title in square brackets and put the rating after the equals.
For example: books["Gravity's Rainbow"] = :splendid
Keep going, fill it up with reviews. And, if you want to see the whole list,
just type: books
Again, the ratings are: :splendid, :quite_good, :mediocre,
:quite_not_good, and :abyssmal.
These ratings are not strings. When you place a colon in front of a simple word, you get a symbol. Symbols are cheaper than strings (in terms of computer memory.) If you use a word over and over in your program, use a symbol. Rather than having thousands of copies of that word in memory, the computer will store the symbol only once.
Once you've got three or four books in
there, type: books.length.
See, the length method works on strings, list and hashes. One great thing about
Ruby is that names are often reused, which means fewer names you need to remember.
If you'd like to look up one of your old reviews, again put the title in the square. But leave off the equals.
Just like this: books["Gravity's Rainbow"]
Keep in mind that hashes won't keep things in order. That's not their job. It'll just pair up two things: a key and a value. In your reviews, the key is the book's title and the value is the rating.
If you want to just see the titles of the books you've reviewed: books.keys
So are you giving out harsh, unfair reviews? Let's keep score with this hash:ratings = Hash.new {0}
Then, okay, now let's count up your reviews. Just stay with me. Type:
books.values.each { |rate| ratings[rate] += 1 }
(The straight line in the code is the pipe character, probably located right above the Enter key on your keyboard.)
Great, wow! You've made a scorecard of your ratings. Type ratings to see the count.
This new hash shows a rating and then the number of times you've given that rating.
One of the amazing new things we've just used is a block. We're going to explore these more in the next summary. But, basically, a block is a bit of Ruby code surrounded by curly braces.
Let's try another block: 5.times { print "Odelay!" }
Blocks are always attached to methods. Like the times method, which takes the
block and runs the code over and over. (In this case: five times.)
This last lesson was a bit longer. You've probably used up three minutes learning about:
{}.:splendid.books.values.each { |rate| ratings[rate] += 1 }.On your computer, you probably have a lot of different files. Files with pictures in them, files with programs in them. And files are often organized into folders, also called: directories.
I've prepared a few directories for you. Take a look:
Dir.entries "/"
You've just listed out everything in the top directory. The root directory, indicated by a single slash. Containing some programs and other tutorials and such.
So, what is the Dir.entries method? Well, it's just a method, right?
entries is a method called on the Dir variable.
And Dir has a collection of methods for checking out file directories.
One other little thing we haven't really talked about openly. Method arguments, highlighted in green.
Dir.entries "/": Anything listed after a method
is considered an attachment.print poem: See, print is an ordinary method. And the
poem is attached. To be printed.print "pre", "event", "ual", "ism" has several arguments, with commas
between them.To list just the text files in that directory: Dir["/*.txt"]
The Dir[] method is like entries but you search for files
with wildcard characters. Here, we see those square brackets again! Notice how
they still mean, "I am looking for _____?"
More specifically: "I am looking for files which end with .txt."
Let's crack open this comics file, then. Here's the way:
print File.read("/comics.txt")
All right! We can start to use files to store things. This is great because normally when we exit Ruby, all our variables will be gone. Ruby, by itself, forgets these things. But if we save things in files, we can read those files in future Ruby escapades.
Hey, and guess what? The /Home directory is yours! I gave it to you! I am generous! Let's make a copy of the comics file.
You'll want to: File.copy('/comics.txt', '/Home/comics.txt')
If you've already created the file, use File.delete('/Home/comics.txt') to trash it.
Okay, you've got a copy. Check it: Dir["/Home/*.txt"]
To add your own comic to the list, let's open the file in append mode.
Start like this: File.open("/Home/comics.txt", "a") do |f|.
So your prompt has changed. See that? Your prompt is a double dot now.
In this tutorial, this prompt means that Ruby is expecting you to type more. As you type in the lines of Ruby code, the double dots will continue until you are completely finished.
Hot tip: If you want to stop working on the code and break out of the double dots, use the reset
command. If you want to go the previous page of the tutorial, use the back command.
Here's your code. You've already typed the first line, so just enter the second line. (The \n
is an Enter character.
File.open("/Home/comics.txt", "a") do |f| f << "Cat and Girl: http://catandgirl.com/\n"endAnd, since you're getting so advanced and capable here, one other tip: you can use the up and down arrow keys to edit your old commands or run them again.
That last line adds the Cat and Girl comic to the list, but Ruby's going to wait until you're totally finished to take action.
Now, to finish the code you've started. You opened a new block when you typed do.
So far the blocks we've seen have used curly braces. This time we'll be using do and end instead
of curly braces. A lot of Rubyists will use do...end when the block goes on for many lines.
Let's get that block finished now, with: end
File.open("/Home/comics.txt", "a") do |f| f << "Cat and Girl: http://catandgirl.com/\n"endGood, good! You've added that new comic to the file. You can see for yourself: print File.read("/Home/comics.txt")
What time was it when you changed the file? Let's check. Type: File.mtime("/Home/comics.txt")
Great, there's the time. The precise time exactly when you added to the file. The mtime gives you a Ruby Time object.
If you want to check just what hour it was, hit the up arrow key and change the line to: File.mtime("/Home/comics.txt").hour
Well done, well done, well done, well done! Truly, truly, truly, truly, truuuuuuuuly!
Here's the last few minutes of your life in review:
You totally know how to use Ruby now. I mean you've got down the essentials. You just need to keep learning more methods and try out more complex blocks.
But there's one side of Ruby we haven't settled. Making your own methods and classes.
Ahem! Let's get it over with then.
Start with: def load_comics( path )
Hey, okay, you done it. You're making your own method. You started with def, followed by the name of the method.
And a list of arguments which the method will need. This isn't too scary and dangerous!
All we have to do is fill it up with Ruby and finish it up with end.
Here's the code:
def load_comics( path ) comics = {} File.foreach(path) do |line| url, name = line.split(': ') comics[url] = name.strip end comicsendNo need to indent, if you don't want. I just do that to make it read easier.
A new method is born. Let us use it: comics = load_comics('/comics.txt')
If you have a problem, you might have mistyped. Use the back command and try again.
In your Ruby window above, look at the code you've typed for the load_comics method. What is happening? You're
passing in the path variable and you're getting back the comics variable. Ruby lets the comics
hash trickle out the end of the method.
A number of methods were used to get the job done. See if you can spot them.
line
variable inside the do...end block took turns with each line in the file.url and name for each comic.Right on. Bravo. You've got the comics in a Ruby hash. But what now? What good is this really?
Let's make a page of links. How about that? We'll need to load a little library I've made for you.
Type: require 'popup'
Excellent, you've loaded the popup library. It's saved in a file in the Libraries folder. See: Dir["/Libraries/*"]
The popup library contains a bunch of methods I've written which let you control a popup here on the Try Ruby site.
Here, try this: Popup.goto "http://google.com/"
Our own lovely, little popup to manipulate. You can also fill it with your own goodies. We'll start small:
Popup.make { h1 "My Links" link "Go to Google", "http://google.com/"}The term h1 (h-one) means a level-one header. In HTML, this is the largest size of header.
Looks good, you did it perfectly, just as you were asked. Let's make a list then.
Here's how you make a list with the popup library:
Popup.make do h1 "Things To Do" list do p "Try out Ruby" p "Ride a tiger" p "(down River Euphrates)" endendThe p method is short for "paragraph".
Okay, this is coming along wonderfully. This is simple stuff, but keep in mind that you didn't know any Ruby whatsoever just fifteen minutes ago!
Last step. Let's tie it all together, you know? Let's make it chime together like a very nice set of glistening chimes on the beach in the maginificent sunlight!
Make sure the comics are loaded: comics = load_comics( '/comics.txt' )
Now, let's make a list of the links to each comic:
Popup.make do h1 "Comics on the Web" list do comics.each do |name, url| link name, url end endendYou can click on the links and read the comics in the little window even! Smashing!
You're a level six Ruby cleric. I mean what a great job you've done. Let's review:
load_comics method several times.require method to load the popup library.require 'popup'So what could possibly be next? What could you possibly have to learn now? Ha, this is the best part. You've come such a long way that we're going to uncover classes. For two more short lessons and you're done.
Earlier, we created a hash like this: Hash.new Try it.
You see, the empty curly braces {} is a shortcut for Hash.new. The new method is used to make objects
of a certain class. (Think "class" as in "working class" a specific group of objects which are similar, have the same jobs, the same shirts.)
Ask yourself this: How would I make a blog in Ruby? Where would you start? Well, you might store your blog entries in a file, right? But how would you keep track of the title of the entry and the time it was posted? And when you loaded the file, how would it look in Ruby? Would it be a Hash? Or an Array? Or an Array of Arrays? Or something else?
I really think you'll want to use a class. You are already familiar with many classes: Hash, Array, String.
Let's make a new class: class BlogEntry.
You've opened up a new BlogEntry class. What is your blog entry made of? A title, sure. Also, a time when the entry was posted. The
full text of the entry.
We'll do a mood setting, too, just like LiveJournal.
The Internet has really brought back stick people and smileys
out of bankruptcy. Emote!
Okay, so you've got the first line of the class, here's the rest:
class BlogEntry attr_accessor :title, :time, :fulltext, :moodendHey, good class, man. You've got a new BlogEntry class. To start an entry: entry = BlogEntry.new.
In the class definition, you used a method called attr_accessor. There are many attribute methods like
this which add little settings to classes. These attributes are just variables attached to a class.
Think of it this way. A class is like a person. That star-shaped human thing out there. And the attributes are the dangling limbs, the different parts that make up a body.
To set the title of your entry: entry.title = "Today Mt. Hood Was Stolen!"
Go ahead and set the post time: entry.time = Time.now
And the mood: entry.mood = :sick
And the post itself: entry.fulltext = "I can't believe Mt. Hood was stolen! I am speechless! It was stolen by a giraffe who drove away
in his Cadillac Seville very nonchalant!!"
To see all your settings, just type at the prompt: entry.
Cool, you're blog is awesome. Hey, let's make things a bit easier on you. You're not going to want to set the time like that every time you post. You just want to type in the title and the entry and the mood quickly, right?
Let's add an initialize method.
class BlogEntry def initialize( title, mood, fulltext ) @time = Time.now @title, @mood, @fulltext = title, mood, fulltext endendOnce you've got that typed in, try making a new entry: BlogEntry.new
Did you see how inside the class we used the at-symbols? Like this: @time = Time.now
Outside the class, we use accessors: entry.time = Time.now But inside we use instance variables: @time = Time.now
They're the exact same thing, but expressed in two different places of your program.
Your blog now needs a title, a mood and a post in order to work. When a new BlogEntry is created, the initialize method
is used to check for any arguments to new. Uh, we need three arguments!
Try it again with all three.
entry2 = BlogEntry.new( "I Left my Hoodie on the Mountain!", :confused, "I am never going back to that mountain and I hope a giraffe steals it." )
Aha, you're here. And all in one piece. We're still going to make your blog real, but until then, let's review, okay?
BlogEntry class.
In other words: you call them BlogEntry objects.entry.time = Time.now)@time = Time.now)Okay, let's wrap things up, kid. Here's the last chapter of the GRIPPING epic story of Try Ruby! Now that you've got a taste of how it all works, how are you going to use it around the house and in your grocer's freezer? You're a great person (one of my favorites), but you need guidance.
Let's finish your blog. You have blog entries, but no actual blog.
Put the entries into an array: blog = [entry, entry2]
Some beautiful things can be done with the simple parts of Ruby, especially when you combine them together into new things. Here we've got a blog made of an array of classes. And, actually, Ruby really does good with this kind of creature.
Here's a few things you can do with your array blog:
blog.sort_by { |entry| entry.time }.reverseblog.find_all { |entry| entry.fulltext.match(/cadillac/i) }/giraffe/i is a Regexp object, used for matching words.blog << new_entryYou can browse a list of all Ruby's built-in methods at ruby-doc.org's core list. Another good list is at the online pickaxe.
One really useful method (I probably use this more than anything else) is map. Type: blog.map { |entry| entry.mood }
The map method cycles through an array and replaces each item with something new. Say you wanted to replace each of your blog entries
with the name Bruce Willis. Do it so: blog.map { "Bruce Willis" }
Since the block always returns the string "Bruce Willis", that's what you get. In the code you just used, the entry was swapped out
for only the entry.mood.
Now, I want you to make a popup with your blog entries. I'm not going to give you all of the code. I'm just going to give you part of it.
blog.each do |entry| h2 entry.title p entry.fulltextendNow, I expect you to put the popup code around it and add an h1 title with the name of your blog. For extra haroompf, have the time of each entry display.
Good, that's it! This is exactly the code you can use to write your own real Ruby blog. If you're feeling adventurous, I'd check out the Rails videos which show a swift young fellow creating a blog in 15 minutes. You just sit back and watch.
I should mention Rails. You have been learning the Ruby language, how to speak it. But Rails is a bunch of libraries (sort of like the popup library we've been using.) It's a very powerful toolkit for building websites. If you're interested in learning about Rails, I would head over there right away. Start using your Ruby skills proper!
One thing Rails has is easy methods for dates. Like, try: Time.now - 2.weeks
If you'd like to start writing little Ruby programs just to practice, I have a project called MouseHole which is a little web toolkit for writing short Ruby programs. You can look over a few scripts to see what I mean.
MouseHole isn't for writing web sites really. It's just for writing little programs you run inside your browser. Like there's a notepad program for MouseHole and a program which adds a mouse picture next to links on the web which link to MouseHole programs.
I've got a MouseHole script inside a file here:
print File.read("/MouseHole/flickrpedia.user.rb")
This last section took a moment to wind down, to give you some pointers as to how you can use Ruby. If you enjoyed yourself, download Ruby and install it.
Once you have Ruby installed, you can use Interactive Ruby by running irb on your system's prompt. For more on Irb,
there's The Tiger's Vest to help you.
You really deserve a double-layer cake with double-double frosting and a guy playing one of those guitars that's a double guitar. I mean you finished, you really did! No doubt about it, you're a certified red-blooded smartiac!