Buy this Book
Print Book $34.99 PDF $24.99 Read it Now!
Print Book £24.99
Add to UK Cart
Reprint Licensing

Learning Ruby
Learning Ruby

By Michael Fitzgerald
Book Price: $34.99 USD
£24.99 GBP
PDF Price: $24.99

Cover | Table of Contents | Colophon


Table of Contents

Chapter 1: Ruby Basics
Perhaps like you, I've learned to program in a number of languages over the years—BASIC, FORTRAN, C, C++, C#, Java, and JavaScript among others—but so far Ruby is my favorite. It has been the most fun to learn and use. Why? Because of its syntax. If you have a background in a variety of other languages, Ruby is easy to figure out. And it's flexible: Ruby lets you do things in a variety of ways, not just one way, so you can decide how to do things your way.
Ruby is an interpreted rather than a compiled language. You can call it a scripting language, an object-oriented language, a refreshing language. It's not a perfect language. It doesn't have to be. It's still my favorite. It has that certain je ne sais quoi. If it didn't, why would I spend hundreds of hours writing a book about it? Certainly not for money and fame.
To me, one of the best aspects of Ruby is its composability. Composability is the degree to which you can express logic by combining and recombining parts of a language (see James Clark's "The Design of RELAX NG" at ). Ruby's got that, big time.
Also, Ruby isn't under committee or corporate control. It's open source. It was written by Matz, with some help from his friends. (It was written in C, by the way, and can take C extensions.)
"Matz" is short for Yukihiro Matsumoto (from Japan). He started working on Ruby in 1993, and first released it to the world in 1995, the same year Java came out. It took a while for Ruby to emerge in the West, but once it did, around the year 2000, it started to take off. With the help of people like Dave Thomas, Andy Hunt, Hal Fulton, and others, Ruby got a foothold. Now it has a fan base.
And Ruby has a killer app. It's called Ruby on Rails (). Heard of it? It's a web application framework for producing web sites with databases quickly and easily. A lot of people really like Rails. Not everyone, but a lot of people. And those people are discovering that one of the main reasons they like Rails is because it was written in Ruby.
I know many readers are expecting a "Hello, World" example right about now. In spite of a moral and ethical obligation to provide a "Hello, World" example, I have decided to change the first example to "." Given all that Matz has done for the programming world, don't you think he deserves some acknowledgment?
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Hello, Matz
I know many readers are expecting a "Hello, World" example right about now. In spite of a moral and ethical obligation to provide a "Hello, World" example, I have decided to change the first example to "." Given all that Matz has done for the programming world, don't you think he deserves some acknowledgment?
Before you go any further, find out if you already have Ruby installed on your computer. If you are on Mac OS X or a Linux distribution of some sort, it might already be there, though it's probably an older version; Tiger (Mac OS X 10.4 or later) ships with version 1.8.2, for example.
To discover if Ruby is lurking inside your box, just go to a shell prompt on a Unix/Linux system (this won't work on a standard Windows system) and type:
$ which ruby
See if you get a reply like this one (good news if you do):
/usr/local/bin/ruby
Or just type a command to check the version of Ruby (this works on Unix/Linux and Windows):
$ ruby -v
or:
$ ruby --version
If Ruby is installed, you should get an answer that looks like this:
ruby 1.8.6 (2007-03-13 patchlevel 0) [powerpc-darwin8.9.0]
If Ruby is not installed on your box, and you're a little nervous about figuring out how to install it on your own, go to the section "," later in this chapter. Follow the instructions there to install Ruby on your platform. Then come right back!
Now that you have Ruby up and running, type the following line in a plain-text editor such as TextPad or vim:
puts "Hello, Matz!"
This line of code is a programming statement, an instruction that you want the program to carry out. The instruction will print the string Hello, Matz! on your screen, followed by a newline character.
You can end a statement with a semicolon (;) if you want, just like in C or Java, but you sure don't have to: a newline will do fine. (Most Ruby programmers don't use ; except when writing multiple statements on one line.)
Save the little program in a file as plain text and name it matz.rb. (The .rb file extension is the conventional extension for Ruby programs.)
It's a good idea to save the file in a directory or folder where you plan to do your Ruby work so that all your Ruby files will be readily accessible in one location.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Interactive Ruby
Interactive Ruby, or irb, is an interactive command-line environment for Ruby, allowing you to see results (or errors) after you enter each statement. When you install Ruby, you get irb along with it.
Start out by typing this at a prompt:
 $ irb -v
In return, you should get irb's version number:
irb 0.9.5(05/04/13)
If irb is present, you are ready to go; if it isn't, go to the section "," later in this chapter, and follow the instructions.
When you enter irb at a shell prompt, you will get the irb prompt. Type a Ruby statement at the prompt, and then press the Return or Enter key:
irb(main):001:0> puts "Hello, Matz! "
Hello, Matz!
=> nil
nil, set off by => in the output of irb, is a value returned by the method puts. nil has a special meaning in Ruby. It denotes empty and always means false.
puts prints out the string Hello, Matz!, followed by a newline character.
The newline character varies, depending on your platform. On Mac OS X and Unix/Linux systems, it is an LF (linefeed) character; on Microsoft Windows, it's CR+LF (a carriage return character followed by a linefeed).
As mentioned earlier, you can assign a string, or just about any other value, to a name (variable), and then reuse it. In the following command, Hello, Matz! is assigned to the name hi and printed by puts:
irb(main):002:0> hi = "Hello, Matz!"
=> "Hello, Matz! "
irb(main):003:0> puts hi
Hello, Matz!
=> nil
Print out hi three times:
irb(main):004:0> puts hi * 3
Hello, Matz! Hello, Matz! Hello, Matz!
=> nil
You can do some simple math:
irb(main):006:0> 10 + 10
=> 20
irb(main):007:0> 4 * 5
=> 20
irb(main):008:0> 100 / 5
=> 20
irb(main):009:0> 50 - 30
=> 20
irb(main):010:0> 80 % 60
=> 20
We could go on and on. irb is a great environment for playing around with Ruby and learning how it works because you always get immediate feedback with every step you take.
You'll have opportunities to fire up irb later in the book. In fact, you can use irb to run any Ruby program that you find here.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Resources
You can find a lot about Ruby at the official Ruby site, . There you can find news, downloads, tutorials, as well as documentation, mailing lists, and other good stuff. Ruby Central, Inc. () runs the annual International Ruby Conference (). It usually gets sold out way early, so plan accordingly.
Aside from the documentation page on ruby-lang.org (), is a great place to hunt down information on all things Ruby. RDoc is a tool that generates documentation from Ruby source code. You can find the Ruby core documentation produced by RDoc at . On the Mac (Tiger or later), a good tool for looking things up quickly is the RDoc widget for Dashboard (see ), thanks to Precision Information Services (). You can download the widget from .
Figure : RDoc widget on Dashboard
Ruby-Talk is the most popular general Ruby mail list. To sign up (easily), go to . You'll also see several other lists at this site. For a more complete list of mail groups, including lists in languages besides English, see .
RubyForge () is the host of a growing number of open source Ruby projects. Some of the more popular projects include Mongrel, a fast HTTP server (), RubyGems (), a dead-simple tool for installing Ruby packages, and Instant Rails (), a single-step Windows installer that includes Ruby, Rails, Apache, and MySQL. The Ruby Application Archive (RAA) at predates RubyForge and is still a popular site for hosting Ruby projects—more than 1,500 and counting.
For future reading, check out Dave Thomas's Programming Ruby, Second Edition, published by Pragmatic (see or ). This book, often referred to as the pickaxe book (for the pickaxe on its cover), is well-written and as complete it could possibly be. You won't be disappointed. You can also find a free, online version of the first edition at .
Hal Fulton's The Ruby Way (Addison-Wesley) is also now in its second edition (). It has also been well-received and is a worthwhile investment. Other books exist, and many more are on the way—too many to list (see )—but I note Dave and Hal's books because they were in the game early, and are still in it.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Installing Ruby
Ruby is available on the major platforms. The following sections show you how to install Ruby on Mac OS X, Windows, and Linux. Ruby's general download page is at . Most of you could likely figure out how to install Ruby just by following the links there, but the material here provides a little extra guidance.
Installation procedures are a moving target, and print media can't keep up with electronic media. That means that some of this material may get out of sync with what's happening out there on the Web, so I'll be as generally specific as I can.
As shipped, Tiger comes with an older version of Ruby. Which version depends on what release of Tiger you're dealing with. The release of Tiger on my system at the moment is 10.4.8, which comes with version 1.8.2. You'll want an updated version, as I did.
The simple way to install Ruby (and a boatload of other software) is with Locomotive (). For information on what comes with the Locomotive download (a dmg file), which includes Ruby on Rails, see . It might be more than you want to deal with. You can find a mirror at . Select a mirror and then follow the steps just like you would when installing any other dmg.
The purest form of installation, at least in my mind, is to download and compile the source files. In other words, you download the file distribution for a given release, pull the files out of the release archive, compile the files (those that need compilation), and then copy those files to their proper directories. Those are the basic steps, but there are a few tools to make this job easier, like configure and make. We'll take advantage of them here as we install a new version of Ruby on Tiger (these steps could apply to a Linux installation as well).
These steps may appear daunting at first, but they really are not. Just follow along and things will come together in the end.
You can find excellent instructions on installing Ruby on Tiger in Dan Benjamin's "Building Ruby, Rails, LightTPD, and MySQL on Tiger" (). He covers installing more software than you need to install now; I'll only use his steps for installing Ruby, and I'll update those steps to include the latest versions of software.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Permission Denied
If you are new to using the shell on Mac OS X or Linux, what do you do when you get a message like this?
-bash: ./matz.rb: Permission denied
This reply most likely means that the file is not set up as an executable. To fix this, change the access control on the file using the chmod command by typing:
chmod 755 matz.rb
755 makes the control list read rwxr-xr-x (where r means read, w write, and x execute). This means that the file is readable and executable by everyone (owner, group, and others, in that order), but writable only by the owner. To find out more about chmod, type man chmod at a shell prompt.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Associating File Types on Windows
This section is for those who use Windows and have never associated a file type before. If this is a familiar topic to you or you are on a different platform, you can skip it.
On its own, Windows doesn't know or care about shebang (#!), which allows the program to execute by merely invoking its name in a shell on Unix/Linux systems. However, you can achieve a similar effect to shebang by creating a file type association with the assoc and ftype commands on Windows.
If you used the One-Click Ruby Installer for installing Ruby on Windows, the following was performed automatically for you, behind the scenes.
First, find out if an association exists for .rb with the assoc command:
C:\Ruby Code>assoc .rb
File association not found for extension .rb
It's not found, so associate the .rb extension with a file type:
C:\Ruby Code>assoc .rb=rbFile
Test to see if the association exists now:
C:\Ruby Code>assoc .rb
.rb=rbFile
Test to see if the file type exists:
C:\Ruby Code>ftype rbfile
File type 'rbfile' not found or no open command associated with it.
It's not found, so create it:
C:\Ruby Code>ftype rbfile="C:\Program Files\Ruby\bin\ruby.exe" "%1" %*
Be sure to put the correct path to the executable for the Ruby interpreter, followed by the substitution variables. %1 is a substitution variable for the file you want to run, and %* accepts all other parameters that may appear on the command line. Test it:
C:\Ruby Code>ftype rbfile
rbfile="C:\Program Files\Ruby\bin\ruby.exe" "%1" %*
Finally, add .rb to the PATHEXT environment variable. Is it there already?
C:\Ruby Code>set PATHEXT
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.tcl
No. What we want isn't there, so let's add it:
C:\Ruby Code>set PATHEXT=.rb;%PATHEXT%
And then test it:
C:\Ruby Code>set PATHEXT
PATHEXT=.rb;.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.tcl
Very good. Now run a Ruby program by entering the program's filename at the command prompt, without the file extension:
C:\Ruby Code> matz
Hello, Matz!
To preserve these settings, you can add these commands to your autoexec.bat file or set the environment variables by selecting Start → Control Panel → System, clicking on the Advanced tab, and then clicking the Environment Variables button.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Review Questions
  1. What is the nickname of the inventor of Ruby?
  2. Ruby came out in 1995. What other programming language was released to the public that year?
  3. Is everyone who writes a programming book morally or otherwise obligated to write a "Hello, World!" program?
  4. What does the abbreviation irb stand for?
  5. What is Ruby's killer app?
  6. What is the name of the funny book on Ruby?
  7. Who wrote the pickaxe book?
  8. What's one of the author's favorite programming environments on the Mac?
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 2: A Quick Tour of Ruby
Without going into all the details, this chapter introduces you to the fundamentals of Ruby: classes and modules, including the Object class and the Kernel module, reserved words (keywords), comments, variables, methods, and so forth. Most topics will be dealt with elsewhere in the book in more detail. Some topics merit entire chapters, others only sections (found in ). I'll always tell you where else to look for more information on a topic. This book's most detailed discussions on methods and blocks are found in this chapter.
Matz, the creator of Ruby, had wanted to create his own programming language since he was in high school. He wanted to create a scripting language, but he also wanted it to be object-oriented.
Ruby goes beyond mere scripting, though its programs may look like shell scripts. It is not just a procedural language, but it can be used like one.
Ruby has classes. Classes hold data—in the form of variables and constants—and methods, which are compact collections of code that help you perform operations on data. Classes can inherit information from each other, but only one at a time. This allows you to reuse code—which means you'll spend less time fixing or debugging code—and intermix the code through inheritance.
A class is like a blueprint; with a new method, this blueprint can be assigned to a variable or become instantiated, and thereby become an object. In Ruby, almost everything is an object; in fact, everything that Ruby can bind to a variable name is an object.
There's lots more to learn about classes, and you'll find a lot more information on classes in . For right now, you can get by with the basics. shows a Ruby program, friendly.rb, that has two classes, Hello and Goodbye. You'll find this program in the archive of Ruby programs that comes with this book (download it from ). Run this program at a shell or command prompt, in the directory where the archive was installed. If a code example is not in a file, you can type that code in irb to see for yourself what it does. I encourage you to run as much code as you dare.
Example . friendly.rb
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Ruby Is Object-Oriented
Matz, the creator of Ruby, had wanted to create his own programming language since he was in high school. He wanted to create a scripting language, but he also wanted it to be object-oriented.
Ruby goes beyond mere scripting, though its programs may look like shell scripts. It is not just a procedural language, but it can be used like one.
Ruby has classes. Classes hold data—in the form of variables and constants—and methods, which are compact collections of code that help you perform operations on data. Classes can inherit information from each other, but only one at a time. This allows you to reuse code—which means you'll spend less time fixing or debugging code—and intermix the code through inheritance.
A class is like a blueprint; with a new method, this blueprint can be assigned to a variable or become instantiated, and thereby become an object. In Ruby, almost everything is an object; in fact, everything that Ruby can bind to a variable name is an object.
There's lots more to learn about classes, and you'll find a lot more information on classes in . For right now, you can get by with the basics. shows a Ruby program, friendly.rb, that has two classes, Hello and Goodbye. You'll find this program in the archive of Ruby programs that comes with this book (download it from ). Run this program at a shell or command prompt, in the directory where the archive was installed. If a code example is not in a file, you can type that code in irb to see for yourself what it does. I encourage you to run as much code as you dare.
Example . friendly.rb
class Hello
  def howdy
    greeting = "Hello, Matz!"
    puts greeting
  end
end

class Goodbye < Hello
  def solong
    farewell = "Goodbye, Matz."
    puts farewell
  end
end

friendly = Goodbye.new
friendly.howdy
friendly.solong
If you run the program in , you'll get these messages back:
$ friendly.rb
Hello, Matz!
Goodbye, Matz.
Experienced programmers can likely tell what's happening in without any tutoring. If you're not one of these, read on; otherwise, you can skip ahead to the next heading (or jump to if you are eager to get the whole story on Ruby classes).
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Ruby's Reserved Words
Every programming language has its own list of reserved words (aka keywords), which are reserved for its own purposes so that it can do its job. They are the words that make statements in programs, and without statements, or instructions, how could a program tell a computer what to do?
lists Ruby's reserved words and briefly describes the purpose of each.
Table : Ruby's reserved words
Reserved word
Description
BEGIN
Code, enclosed in { and }, to run before the program runs.
END
Code, enclosed in { and }, to run when the program ends.
alias
Creates an alias for an existing method, operator, or global variable.
and
Logical operator; same as && except and has lower precedence. (Compare with or.)
begin
Begins a code block or group of statements; closes with end.
break
Terminates a while or until loop or a method inside a block.
\case
Compares an expression with a matching when clause; closes with end. (See when.)
class
Defines a class; closes with end.
def
Defines a method; closes with end.
defined?
A special operator that determines if a variable, method, super method, or block exists.
do
Begins a block and executes code in that block; closes with end.
else
Executes following code if previous conditional, in if, elsif, unless, or when, is not true.
elsif
Executes following code if previous conditional, in if or elsif, is not true.
end
Ends a code block (group of statements) starting with begin, def, do, if, etc.
ensure
Always executes at block termination; use after last rescue.
false
Logical or Boolean false, instance of FalseClass. (See true.)
for
Begins a for loop; used with in.
if
Executes code block if conditional statement is true. Closes with end. (Compare with unless, until.)
in
Used with for loop. (See for.)
module
Defines a module; closes with end.
next
Jumps before a loop's conditional. (Compare with redo.)
nil
Empty, uninitialized variable, or invalid, but not the same as zero; object of NilClass.
not
Logical operator; same as !.
or
Logical operator; same as || except or has lower precedence. (Compare with and.)
redo
Jumps after a loop's conditional. (Compare with
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Comments
A comment hides lines from the Ruby interpreter so that the lines are discarded or ignored. This allows a programmer (that's you) to insert all kinds of information in a program so that other people can figure out what's going on. There are two basic comment styles in Ruby. The hash character (#) can be at the beginning of a line:
# I am a comment. Just ignore me.
Or on the same line after a statement or expression:
name = "Floydene Wallup" # ain't that a name to beat all
You can make a comment run over several lines, like this:
# This is a comment.
# This is a comment, too.
# This is a comment, too.
# I said that already.
Here is another form. This block comment conceals several lines from the interpreter with =begin/=end:
=begin
This is a comment.
This is a comment, too.
This is a comment, too.
I said that already.
=end
A block can comment out one line or as many lines as you want.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Variables
A variable is an identifier or name that can be assigned a value, and a value has, or will have, a type at runtime (when the program runs). An example is found in the following statement, where the variable x is assigned the value 100 by the equals sign.
x = 100
Now the local variable x holds the value 100. But, hey, what type is it? Looks like an integer to me—how about you? And what does Ruby think?
Many modern programming languages, like C++ and Java, are statically typed. This basically means that a variable is assigned a type at the time it is declared, and, because these languages are also strongly typed, the variable remains that type unless it is cast into a different type, if it is possible to do so.
For example, in Java, you would declare variables with the types (int) on the left:
int months = 12;
int year = 2007;
Ruby doesn't have type declarations. It just assigns values to variables, like this:
months = 12
year = 2007
You could use a semicolon at the end of the line if you wanted, but a newline character is all you really need.
The values in x, months, and year are clearly integers, but you didn't have to give them a type because Ruby does that for you, automatically. It's called dynamic or duck typing.
This is how duck typing works: if you observe an aquatically competent bird, and it walks like a duck, quacks like a duck, flies like a duck, and swims like a duck, well, by George, it's probably a duck. Ruby likewise looks at a value assigned to a variable, and if it walks, quacks, flies, and swims like an integer, then Ruby assumes it can act as an integer.
Let's ask Ruby what it thinks of x—that is, whether it is an integer—with the kind_of? method (this method is from the Object class).
x.kind_of? Integer # => true
Why yes, the value of x behaves like an integer! As a matter of fact, it is an instance of the Fixnum class, which inherits the Integer class.
x.class # => Fixnum
Change the value of x from an integer to a floating point with the to_f method from the Fixnum class (it is inherited by other classes, too).
x.to_f # => 100.0
As I noted in , whenever you see
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Strings
A string is a sequence of letters, numbers, and other characters. There are several ways to create a string in Ruby, but probably the simplest way is just to write it out, surrounded in quotes (double or single quotes will do). Here we have a quote from Thoreau's Walden:
thoreau = "If a man does not keep pace with his companions, perhaps it is because
he hears a different drummer."
With String methods, you can access and manipulate the string thoreau. For example, you can retrieve part of a string with the [] method, using a range. Let's grab characters 37 through 46:
thoreau[37..46] # => "companions"
Or, starting at the end of the string using negative numbers, get the second to last character through the eighth to last:
thoreau[-8..-2] # => "drummer"
You can iterate over all the characters in the string using a block that munches on every byte (8-bit sequence) in an ASCII string and generates a character (with the chr method), separating each character with a slash:
thoreau.each_byte do |c|
  print c.chr, "/"
end
# => I/f/ /a/ /m/a/n/ /d/o/e/s/ /n/o/t/ /k/e/e/p/ /p/a/c/e/ /w/i/t/h/ /h/i/s/
/c/o/m/p/a/n/i/o/n/s/,/ /p/e/r/h/a/p/s/ /i/t/ /i/s/ /b/e/c/a/u/s/e/ /h/e/ /h/e/a/r/s/
/a/ /d/i/f/f/e/r/e/n/t/ /d/r/u/m/m/e/r/./
If you want to use something beyond ASCII characters in your programs, you should read this note; otherwise, it may be more information than you need. I must admit, implying that a character is synonymous with a byte is rather old-fashioned. In the broader, Unicode-based world, characters can be represented by more than one byte. For example, the character encoding UTF-8 represents characters with one to four bytes. By default, Ruby uses ASCII character encoding, but you can change the encoding by setting (early in the program) the $KCODE variable to 'u' (for UTF-8), 'e' (for EUC), 's' (for SJIS), or 'a' or 'n' (for ASCII or NONE).
Incidentally, the chr method converts a character code (which each_byte produces) into an actual character. You should also know about the opposite method—the ? operator, which returns a character code from a character. I'll demonstrate that with
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Numbers and Operators
In most any object-oriented programming language, numbers are considered to be fundamental atoms called primitives. They are not directly associated with a class; they just are. Not so with Ruby: even numbers are instances of classes.
For example, the number 1001, a positive integer, is an instance of the Fixnum class, which is a child class of Integer, which is a child class of Numeric. The number 1001.0, a floating point value, is an instance of the Float class, which is also a child class of Numeric. ( shows the relationships between these classes.)
Along with numbers come operations on those numbers. For example, you can add, subtract, divide, multiply, raise a number to a power (exponentiation), and return the remainder of division (modulo), to name a few.
A great place to get acquainted with math operations in Ruby is with irb. Try these in irb:
irb(main):001:0> 3 + 4 # add
=> 7
irb(main):002:0> 7 - 3 # subtract
=> 4
irb(main):003:0> 3 * 4 # multiply
=> 12
irb(main):004:0> 12 / 4 # divide
=> 3
irb(main):005:0> 12**2 # raise to a power (exponent)
=> 144
irb(main):006:0> 12 % 7 # modulo (remainder)
=> 5
Here are a few of Ruby's assignment operators in action:
irb(main):007:0> x = 12 # assignment
=> 12
irb(main):008:0> x += 1 # abbreviated assignment add
=> 13
irb(main):009:0> x -= 1 # abbreviated assignment subtract
=> 12
irb(main):010:0> x *= 2 # abbreviated assignment multiply
=> 24
irb(main):011:0> x /= 2 # abbreviated assignment divide
=> 12
Ruby also has a Math module that provides all kinds of math functions (in the form of class methods), like square root, cosine, tangent, and so forth. Here is an example call to the class method sqrt from the Math module:
irb(main):012:0> Math.sqrt(16)
=> 4.0
Ruby also delivers some special math classes, such as Rational for doing fractions. You'll learn much more about numbers and operators in . shows all of Ruby's math operators, including operator precedence.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Conditional Statements
Like any programming language, Ruby has conditional statements that test whether a given statement is true or false. It then runs code in a block, based on the answer. Here is a quick example of an if statement that tests whether a variable has a value of zero:
value = 0

if value.zero? then
  puts "value is zero. Did you guess that one?"
end
The zero? method returns true if the value of value is zero, which it is, so the statement following is executed (and any other statements in the code block if/end). By Ruby convention, any method in Ruby that ends with a question mark returns a Boolean, either true or false. This convention is not enforced, however.
Other conditionals include familiar ones like case and while, and less familiar ones like until and unless. covers all of the conditional statements you'll find in Ruby.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Arrays and Hashes
An array is an ordered sequence of indexed values, with an index starting at zero. It is one of the most common data structures in computer science. Here is what an array looks like in Ruby:
pacific = [ "Washington", "Oregon", "California"]
The array is named pacific. It holds three strings—the names of the three states that make up the west coast of the United States. These strings are the elements of the array. The elements of an array can be of any Ruby kind, not just strings, of course. This is only one way to define an array. There are a number of other ways you could do this, as you'll see in .
If you wanted to access one of these elements, you could do it by specifying an index with a method. For example, to access the first element, whose index is zero, you could use the [] method.
pacific[0] # => "Washington"
Calling this method retrieves the value of element 0, Washington. You can learn all about Ruby arrays in .
A hash is a map of keys to values. It is also a very common data structure. Unlike an array, which indexes elements with positive integers, hashes let you choose how you will index the values with a key of your choice. Here is how you do it:
pacific = { "WA" => "Washington", "OR" => "Oregon", "CA" => "California" }
The hash definition is enclosed in curly braces, whereas an array is defined in square brackets. Also, each value is associated (=>) with a key. One of the ways you can access the values in a hash is by their keys. To access the value Oregon from the hash, you could use Hash's [] method.
pacific["OR"] # => "Oregon"
Using the key OR returns the value Oregon. The keys and values can be of any kind, not just strings. You can learn more about hashes in .
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Methods
Methods provide a way to gather code (statements and expressions) into one place so that you can use it conveniently and, if necessary, repeatedly. You can define methods to do all kinds of things. In fact, most of the math operators in Ruby are actually methods.
This is the most concentrated discussion on methods that you'll find in this book, so you may find yourself coming back to this section after you have read further.
Here is a simple definition for a method named hello, created with the keywords def and end:
def hello
  puts "Hello, Matz!"
end

hello # => Hello, Matz!
The hello method simply outputs a string with puts. On the flip side, you can undefine a method with undef.
undef hello # undefines the method named hello

hello # try calling this method now
NameError: undefined local variable or method 'hello' for main:Object
        from (irb):11
        from :0
You can also define methods that have arguments, as shown here in the repeat method:
def repeat( word, times )
 puts word * times
end

repeat("Hello! ", 3) # => Hello! Hello! Hello!
repeat "Good-bye! ", 4 # => Good-bye! Good-bye! Good-bye! Good-bye!
The repeat method has two arguments, word and times. You can call a method that has arguments with or without parentheses around the arguments. You can even define method arguments without parentheses, but I don't usually do it that way.
Because you don't have to use parentheses, it is possible to have normal-looking math equations when you use operator methods, such as +. Each line that follows is actually a valid call to the Fixnum + method:
10 + 2 # => 12
10.+ 2 # => 12
(10).+(2) # => 12
Methods have return values. In other languages, you can explicitly deliver a return value with a return statement. In Ruby, the last value in a method is returned, with or without an explicit return statement. This is a Ruby idiom. Here's how to do it in irb:
  1. First, define a method matz that just contains a string:
    rb(main):001:0> def matz
    irb(main):002:1>   "Hello, Matz!"
    irb(main):003:1> end
    => nil
    
  2. Call the matz method, and you will see its output. This is available in
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Blocks
A block in Ruby is more than just a code block or group of statements. In a certain context, a block has a special meaning. This kind of block is always invoked in conjunction with a method, as you will see. In fact, it is referred to as a nameless function.
A block in Ruby is often (but not always) an idiom for getting all the values out of a data structure by iterating over the structure. It sort of means, "give me everything you've got in there, one at a time." I'll show you a common use of the block.
Remember the array pacific? Here it is again:
pacific = [ "Washington", "Oregon", "California" ]
You can call a block on pacific to retrieve all of its elements, one at a time, with the each method. Here is one way to do it:
pacific.each do |element|
 puts element
end
The name between the pipe characters (|element|) can be any name you want. The block uses it as a local variable to keep track of every element in the array, and later uses it to do something with the element. This block uses puts to print each element in the array:
Washington
Oregon
California
You can replace do/end with a pair of braces, as is commonly done, to make things a bit tighter (by the way, braces actually have a higher precedence than do/end):
pacific.each { |e| puts e }
Many dozens of classes have each methods in them, such as Array, Hash, and String. But don't get the wrong idea. Iterating over data structures isn't the only way to use blocks. Let me give you a simple example using yield, a Ruby keyword.
First, define a tiny little method gimme that contains nothing more than a yield statement:
def gimme
  yield
end
To find out what yield does, call gimme alone and see what happens:
gimme
LocalJumpError: no block given
        from (irb):11:in `gimme'
        from (irb):13
        from :0
You get an error here because the job of yield is to execute the code block that is associated with the method. That was missing in the call to gimme. We can avoid this error by using the block_given? method from Kernel. Redefine gimme with an if statement:
def gimme
  if block_given?
    yield
  else
    puts "I'm blockless!"
  end
end
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Symbols
Ruby has a special object called a symbol. All you really need to remember about symbols at this point is that they are like placeholders for identifiers and strings. You can recognize symbols because they are always prefixed by a colon (:).
You don't directly create a symbol by assigning a value to it. You create a symbol by calling the to_sym or intern methods on a string or by assigning a symbol to a symbol. To understand this better, let's take a string on a roundtrip from a string to a symbol and back to a string.
name = "Matz"
name.to_sym # => :Matz
:Matz.id2name # => "Matz"
name == :Matz.id2name # => true
Are your palms getting sweaty? I know symbols may look a little confusing. They are somewhat abstract, because you don't really see what is going on under the Ruby interpreter's hood. On the surface you see that the content of the string name is magically transformed into the label of a symbol. So what?
The "so what" is that once a symbol is created, only one copy of the symbol is held in a single memory address, as long as the program is running. Because of this, rather than making copy after copy, Ruby keeps referring back to that single memory address. This makes Ruby programs more efficient because they don't gobble up as much memory.
Ruby on Rails uses lots of symbols, and it's likely that as you become better acquainted with them, you will use lots of symbols, too. In fact, Ruby uses tons of symbols internally. To prove it, execute this line of Ruby code:
Symbol.all_symbols
You'll get more than 1,000 symbols in your lap!
If you are an experienced Java or C# programmer, this analogy will help: symbols in Ruby are like interned strings, held in a string intern pool.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Exception Handling
Like Java, C++, and other languages, Ruby offers exception handling. An exception occurs when a program commits a transgression, and the normal flow of that program is interrupted. Ruby is prepared to handle such problems, but you can manage them in your own way using Ruby's exception handling.
Java and C++ have try blocks; in Ruby, you would just use a begin block. catch statements in Java and C++ are used where Ruby has rescue statements. Where Java uses a finally clause, Ruby uses ensure.
You will learn how to use exception handling in .
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Ruby Documentation
When I say "," I am mostly referring to the documentation that is generated by RDoc (), a program that extracts documentation from Ruby source files, both C and Ruby files.
The documentation is stored in comments in the source files, and encoded so that RDoc can easily find it. For example, equals signs (such as ===) on the left margin set off a heading, and indented text is formatted as code. RDoc can generate output as HTML, XML, ri (Ruby information), or Windows help (chm) files.
To view the RDoc-generated HTML documentation for Ruby, go to . If you have Ruby documentation installed on your system, which you likely do if you followed the installation instructions in , you can type something like the following at a shell prompt to get formatted documentation in return. Type:
ri Kernel.print
and you will get output that looks like:
----------------------------------------------------------- Kernel#print
     print(obj, ...)    => nil
------------------------------------------------------------------------
     Prints each object in turn to +$stdout+. If the output field
     separator (+$,+) is not +nil+, its contents will appear between
     each field. If the output record separator (+$\+) is not +nil+, it
     will be appended to the output. If no arguments are given, prints
     +$_+. Objects that aren't strings will be converted by calling
     their +to_s+ method.

        print "cat", [1,2,3], 99, "\n"
        $, = ", "
        $\ = "\n"
        print "cat", [1,2,3], 99

     _produces:_

        cat12399
        cat, 1, 2, 3, 99
In , you'll find a tutorial on creating documentation with RDoc.
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Review Questions
  1. What is one of the main differences between a class and a module?
  2. What module does the Object class include?
  3. What syntax do you use to form block comments?
  4. What special character begins an instance variable? A class variable? A global variable?
  5. What is the main feature that distinguishes a constant?
  6. When a method ends with a ?, what does that signify by convention?
  7. A block is a sort of nameless _____________.
  8. What is a proc?
  9. What is the most important characteristic of a symbol?
  10. What is RDoc?
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
Chapter 3: Conditional Love
Many of Ruby's control structures, such as if and while, are standard fare and quite familiar to programmers, while others, like unless and until, are not. Think of control structures, which contain conditional statements, as lie detector tests. In every instance, when you use a control structure with a conditional, you are asking if something is true or false. When you get the desired answer—true or false depending on how you've designed your code—the code block associated with the control is executed.
Two related structures, rescue and ensure, which are used for exception handling, are not explained here. They are discussed in .
This chapter introduces you to Ruby's control structures with plenty of examples, as usual. We'll start out with the if statement—one of the most common structures in just about any programming language.
Let's start out really simple and build from there.
if 1 == 1 then
  print "True!"
end
If it's true that 1 equals (==) 1, which it does, then the if statement returns true, and the code block, consisting only of a print statement, will execute. (This if statement, by the way, could be typed out on one line.)
Now you'll create a variable and compare it with a number. If the variable and number are equal, the code is executed.
x = 256
if x == 256
  puts "x equals 256"
end
# => x equals 256
Notice that we dropped then from the if statement. You don't have to use it in this instance. In addition, you don't have to use end if you write this code all on one line, like so:
x = 256
if x == 256 then puts "x equals 256" end
In fact, you can change the order of things, placing if after puts, and you can drop then and end.
x = 256
puts "x equals 256" if x == 256
When you change the order like this, the if is referred to as a statement modifier. You can do this with other control structures, as you will see later on.
Another way you can lay out an if statement is by replacing the then with a colon (:), like this:
x = 256
if x == 256: puts "x equals 256" end
Play with that code a little bit. Change the value of x so that it won't return true when fed to
Additional content appearing in this section has been removed.
Purchase this book now or read it online at Safari to get the whole thing!
The if Statement
Let's start out really simple and build from there.
if 1 == 1 then
  print "True!"
end
If it's true that 1 equals (==) 1, which it does, then the if statement returns true, and the code block, consisting only of a print statement, will execute. (This if statement, by the way, could be typed out on one line.)
Now you'll create a variable and compare it with a number. If the variable and number are equal, the code is executed.
x = 256
if x == 256
  puts "x equals 256"
end
# => x equals 256
Notice that we dropped then from the if statement. You don't have to use it in this instance. In addition, you don't have to use end if you write this code all on one line, like so:
x = 256
if x == 256 then puts "x equals 256" end
In fact, you can change the order of things, placing if after puts, and you can drop then and end.
x = 256
puts "x equals 256" if x == 256
When you change the order like this, the if is referred to as a statement modifier. You can do this with other control structures, as you will see later on.
Another way you can lay out an if statement is by replacing the then wit