PDF Programming Ruby 1 9 2 0 The Pragmatic Programmers Guide Fourth Edition Dave Thomas download
PDF Programming Ruby 1 9 2 0 The Pragmatic Programmers Guide Fourth Edition Dave Thomas download
https://ebookfinal.com/download/agile-web-development-with-rails-a-
pragmatic-guide-1st-edition-dave-thomas/
https://ebookfinal.com/download/fxruby-create-lean-and-mean-guis-with-
ruby-pragmatic-programmers-1st-edition-lyle-johnson/
https://ebookfinal.com/download/sas-certification-prep-guide-advanced-
programming-for-sas-9-fourth-edition-sas-institute/
https://ebookfinal.com/download/pragmatic-unit-testing-in-c-with-
nunit-pragmatic-programmers-1st-edition-andy-hunt/
Programming Java 2 micro edition on Symbian OS a developer
s guide to MIDP 2 0 Martin De Jode
https://ebookfinal.com/download/programming-java-2-micro-edition-on-
symbian-os-a-developer-s-guide-to-midp-2-0-martin-de-jode/
https://ebookfinal.com/download/maple-9-advanced-programming-
guide-1st-edition-monagan/
https://ebookfinal.com/download/base-sas-9-1-procedures-guide-
volumes-1-2-3-and-4-1st-edition-sas-institute/
https://ebookfinal.com/download/essential-xna-game-
studio-2-0-programming-1st-edition-jim-perry/
https://ebookfinal.com/download/ruby-programming-1st-edition-jerry-
lee-ford/
Programming Ruby 1 9 2 0 The Pragmatic Programmers
Guide Fourth Edition Dave Thomas Digital Instant
Download
Author(s): Dave Thomas, Andy Hunt, Chad Fowler
ISBN(s): 9781937785499, 1937785491
Edition: Fourth Edition
File Details: PDF, 16.05 MB
Year: 2013
Language: english
Download from Wow! eBook <www.wowebook.com>
Download from Wow! eBook <www.wowebook.com>
Programming Ruby 1.9 & 2.0
The Pragmatic Programmers’ Guide
Dave Thomas
with Chad Fowler
Andy Hunt
Preface . . . . . . . . . . . . . . . . xi
Road Map . . . . . . . . . . . . . . . xv
2. Ruby.new . . . . . . . . . . . . . . . 15
2.1 Ruby Is an Object-Oriented Language 15
2.2 Some Basic Ruby 17
2.3 Arrays and Hashes 20
2.4 Symbols 21
2.5 Control Structures 23
2.6 Regular Expressions 24
2.7 Blocks and Iterators 25
2.8 Reading and ’Riting 27
2.9 Command-Line Arguments 28
2.10 Onward and Upward 28
6. Standard Types . . . . . . . . . . . . . . 83
6.1 Numbers 83
6.2 Strings 86
6.3 Ranges 90
7. Regular Expressions . . . . . . . . . . . . . 93
7.1 What Regular Expressions Let You Do 93
7.2 Ruby’s Regular Expressions 94
7.3 Digging Deeper 96
7.4 Advanced Regular Expressions 105
9. Expressions . . . . . . . . . . . . . . 125
9.1 Operator Expressions 126
9.2 Miscellaneous Expressions 127
9.3 Assignment 128
9.4 Conditional Execution 132
9.5 case Expressions 136
9.6 Loops 138
9.7 Variable Scope, Loops, and Blocks 142
Index . . . . . . . . . . . . . . . . 833
Why Ruby?
When Andy and I wrote the first edition, we had to explain the background and appeal of
Ruby. Among other things, we wrote, “When we discovered Ruby, we realized that we’d
found what we’d been looking for. More than any other language with which we have
worked, Ruby stays out of your way. You can concentrate on solving the problem at hand,
instead of struggling with compiler and language issues. That’s how it can help you become
a better programmer: by giving you the chance to spend your time creating solutions for
your users, not for the compiler.”
That belief is even stronger today. More than thirteen years later, Ruby is still my language
of choice: I use it for client applications and web applications. I use it to run our publishing
business (our online store, http://pragprog.com, is more than 40,000 lines of Rails code), and I
use it for all those little programming jobs I do just to get things running smoothly.
In all those years, Ruby has progressed nicely. A large number of methods have been added
to the built-in classes and modules, and the size of the standard library (those libraries
included in the Ruby distribution) has grown tremendously. The community now has a
standard documentation system (RDoc), and RubyGems has become the system of choice
for packaging Ruby code for distribution. We have a best-of-breed web application frame-
work, Ruby on Rails, with others waiting in the wings. We are leading the world when it
comes to testing, with tools such as RSpec and Cucumber, and we’re working through the
hard problems of packaging and dependency management. We’ve matured nicely.
But Ruby is older than that. The first release of this book happened on Ruby’s 20th birthday
(it was created on February 24, 1993). The release of Ruby 2.0 is a celebration of that
anniversary.
Ruby Versions
1
This version of the PickAxe documents both Ruby 2.0 and Ruby 1.9.3.
Exactly what version of Ruby did I use to write this book? Let’s ask Ruby:
$ ruby -v
ruby 2.0.0p0 (2013-02-24 revision 39474) [x86_64-darwin12.2.0]
This illustrates an important point. Most of the code samples you see in this book are actually
executed each time I format the book. When you see some output from a program, that
output was produced by running the code and inserting the results into the book.
Resources
Visit the Ruby website at http://www.ruby-lang.org to see what’s new. Chat with other Ruby
users on the newsgroup or mailing lists (see Appendix 1, Support, on page 829).
And I’d certainly appreciate hearing from you. Comments, suggestions, errors in the text,
and problems in the examples are all welcome. Email us at rubybook@pragprog.com.
2
If you find errors in the book, you can add them to the errata page. If you’re reading the
PDF version of the book, you can also report an erratum by clicking the link in the page
footers.
You’ll find links to the source code for almost all the book’s example code at http://www.prag-
prog.com/titles/ruby4.
1. Ruby version numbering used to follow the same scheme used for many other open source projects.
Releases with even minor version numbers—1.6, 1.8, and so on—were stable, public releases. These
are the releases that are prepackaged and made available on the various Ruby websites. Development
versions of the software had odd minor version numbers, such as 1.5 and 1.7. However, in 2007 Matz
broke with convention and made 1.9 a stable public release of Ruby.
2. http://www.pragprog.com/titles/ruby4/errata.html
Acknowledgments
The first International Ruby Conference had something like 32 attendees. We could all fit
into the tiny hotel bar and talk the night away. Things have changed. The annual conference
now sells out many hundreds of seats within hours, and an increasing number of secondary
conferences have sprung up to meet the needs of folks who can’t get to RubyConf.
As the community has grown, so has Ruby. The language and its libraries are now many
times bigger than they were back when the first edition of this book came out.
And as the language has grown, so has this book. The PickAxe is now massive, mostly
because I still want to document every single built-in class, module, and method. But a book
of this size can never be a solo undertaking. This edition builds on the work from the first
two editions, which included major contributions from Chad Fowler and Andy Hunt. Just
as significant, all three editions have been works created by the Ruby community. On the
mailing lists, in the forums, and on this book’s errata pages, hundreds of people have con-
tributed ideas, code, and corrections to make it better. As always, I owe every one of you a
big “thank you!” for all you have done and for all that you do. The Ruby community is still
as vibrant, interesting, and (mostly) friendly as it ever was—that’s quite an achievement
given the explosive growth we’ve enjoyed.
For the third (tenth anniversary) printing, Wayne E. Seguin was kind enough to check the
section on the wonderful tool RVM, and Luis Lavena checked the section on installing under
Windows, as well as the chapter on running Ruby on Windows. And I’d like to call Anthony
Burns a hero for doing an amazing job of reading through the changes as I was writing them,
3
but that would take away from the fact that he’s a true hero.
Getting this book into production has also been a challenge. Kim Wimpsett is the world’s
best copy editor—she’s the only copy editor I know who finds errors in code and fixes XML
markup. Any remaining errors in this book are a result of my mistyping her suggested cor-
rections. And, as we raced to get the book to the printer in time for RubyConf X, Janet Furlow
patiently kept us all on track.
Finally, I’m still deeply indebted to Yukihiro “Matz” Matsumoto, the creator of Ruby.
Throughout this prolonged period of growth and change, he has remained helpful, cheery,
and dedicated to polishing this gem of a language. The friendly and open spirit of the Ruby
community is a direct reflection of the person at its center.
Thank you all. Domo arigato gozaimasu.
Dave Thomas
The Pragmatic Programmers
dave@pragprog.com
June 2013
3. http://www.flickr.com/photos/pragdave/sets/72157625046498937/
Notation Conventions
Literal code examples are shown using a sans-serif font:
class SampleCode
def run
#...
end
end
Within the text, Fred#do_something is a reference to an instance method (in this case the method
4
do_something) of class Fred, Fred.new is a class method, and Fred::EOF is a class constant. The
decision to use a hash character to indicate instance methods was a tough one. It isn’t valid
Ruby syntax, but we thought that it was important to differentiate between the instance and
class methods of a particular class. When you see us write File.read, you know we’re talking
about the class method read. When instead we write File#read, we’re referring to the instance
method read. This convention is now standard in most Ruby discussions and documentation.
This book contains many snippets of Ruby code. Where possible, we’ve tried to show what
happens when they run. In simple cases, we show the value of expressions on the same line
as the expression. Here’s an example:
a = 1
b = 2
a + b # => 3
Here, you can see that the result of evaluating a + b is the value 3, shown to the right of the
arrow. Note that if you were to run this program, you wouldn’t see the value 3 output—
you’d need to use a method such as puts to write it out.
At times, we’re also interested in the values of assignment statements:
a = 1 # => 1
a + 2 # => 3
If the program produces more complex output, we show it after the program code:
3.times { puts "Hello!" }
produces:
Hello!
Hello!
Hello!
In some of the library documentation, we wanted to show where spaces appear in the output.
You’ll see these spaces as ␣ characters.
Command-line invocations are shown with literal text in a regular font, and parameters you
supply are shown in an italic font. Optional elements are shown in brackets.
ruby ‹ flags ›* progname ‹ arguments ›*
4. In some other Ruby documentation, you may see class methods written as Fred::new. This is perfectly
valid Ruby syntax; we just happen to think that Fred.new is less distracting to read.
to take the slower approach and keep going with the tutorial that follows, or you can skip
ahead to the gritty details starting in Part III, followed by the library reference in Part IV.
Experts, gurus, and “I-don’t-need-no-stinking-tutorial” types can dive straight into the lan-
guage reference in Chapter 22, The Ruby Language, on page 297; skim the library reference;
and then use the book as a (rather attractive) coffee coaster.
Of course, nothing is wrong with just starting at the beginning and working your way
through page by page.
And don’t forget, if you run into a problem that you can’t figure out, help is available. For
more information, see Appendix 1, Support, on page 829.
Facets of Ruby
Getting Started
Before we start talking about the Ruby language, it would be useful if we helped you get
Ruby running on your computer. That way, you can try sample code and experiment on
your own as you read along. In fact, that’s probably essential if you want to learn Ruby—
get into the habit of writing code as you’re reading. We will also show you some different
ways to run Ruby.
The path to a file or directory is the set of directories that you have to traverse to get to it
from the top-level directory, followed by the name of the file or directory itself. Each compo-
nent in this name is separated by a forward slash (on Unix) or a backslash (on Windows).
So, if you organized your projects in a directory called projects under the top-level directory
and if the projects directory had a subdirectory for your time_planner project, the full path to
the README file would be /projects/time_planner/readme.txt on Unix and C:\projects\time_plan-
ner\readme.txt on Windows.
To navigate to a directory, use the cd command. (Because the Unix prompt varies from system
to system, we’ll just use a single dollar sign to represent it here.)
$ cd /projects/time_planner (on Unix)
C:\> cd \projects\time_planner (on Windows)
On Unix boxes, you probably don’t want to be creating top-level directories. Instead, Unix
gives each user their own home directory. So, if your username is dave, your home directory
might be located in /usr/dave, /home/dave, or /Users/dave. At the shell prompt, the special char-
acter ~ (a single tilde) stands for the path to your home directory. You can always change
directories to your home directory using cd ~, which can also be abbreviated to just cd.
To find out the directory you’re currently in, you can type pwd (on Unix) or cd on Windows.
So, for Unix users, you could type this:
$ cd /projects/time_planner
$ pwd
/projects/time_planner
$ cd
$ pwd
/Users/dave
You can create a new directory under the current directory using the mkdir command:
$ cd /projects
$ mkdir expense_tracker
$ cd expense_tracker
$ pwd
/projects/expense_tracker
Notice that to change to the new directory, we could just give its name relative to the current
directory—we don’t have to enter the full path.
We suggest you create a directory called pickaxe to hold the code you write while reading
this book:
$ mkdir ~/pickaxe (on Unix)
C:\> mkdir \pickaxe (on Windows)
Get into the habit of changing into that directory before you start work:
$ cd ~/pickaxe (on Unix)
C:\> cd \pickaxe (on Windows)
Installing on Windows
There are two options for installing Ruby on Windows. The first is a simple installer pack-
age—download it, and you’ll have Ruby up and running in minutes. The second is slightly
more complex but gives you the flexibility of easily managing multiple Ruby environments
on the same computer at the same time. Whichever option you choose, you’ll first need to
download and install a working Ruby.
Select Start Command Prompt with Ruby to open a copy of the Windows command shell with
the environment set up to run Ruby.
You’ve now registered that Ruby interpreter with pik. At any other command prompt, you
can use the pik command to list the Ruby interpreters pik knows about and to tell pik to
make a particular interpreter current:
C:\>pik list
193: ruby 1.9.3p0 (2011-10-30) [i386-mingw32]
C:\>ruby -v
ruby 1.9.3p0 (2011-10-30) [i386-mingw32]
Having gotten one Ruby registered with pik, let’s install another. We’ll play with JRuby, an
implementation of Ruby written in Java. Before doing this, you’ll need to download the Java
runtime (Google is your friend). Once Java is installed, tell pik to install the JRuby interpreter:
C:\> pik install jruby
** Downloading: http://jruby.org......downloads/1.5.2/jruby-bin-1.5.2.zip
to: C:\Users\dave\.pik\downloads\jruby-bin-1.5.2.zip
** Extracting: C:\Users\dave\.pik\downloads\jruby-bin-1.5.2.zip
to: C:\Users\dave\.pik\rubies\JRuby-152
done
** Adding: 152: jruby 1.5.2 (ruby 1.8.7 patchlevel 249) (2010-08-20 1c5e29d)
(Java HotSpot(TM) Client VM 1.6.0_21) [x86-java]
Located at: C:\Users\dave\.pik\rubies\JRuby-152\bin
You now have two Ruby interpreters managed by pik. You can switch between them at the
command line:
C:\>pik list
152: jruby 1.5.2 (ruby 1.8.7 patchlevel 249) (2010-08-20 1c5e29d) (Java H...
193: ruby 1.9.3p0 (2011-10-30) [i386-mingw32]
If you plan on installing gems that have native code components (that is, they interface to
existing Windows libraries using C code), you’ll need a C development environment on
your machine, and you’ll need to download and install the Pik development kit.
Now that you’re all set up, skip forward to Source Code from This Book on page 9.
Installing RVM
Although you can install RVM using RubyGems (assuming you already have a working
Ruby on your system), the preferred approach is to install it directly.
2
Most Unix-like systems will already have all the dependencies installed. The possible fly
in the ointment is Ubuntu, where the curl utility is not installed by default. Add it before you
start with this:
$ sudo apt-get update
$ sudo apt-get install curl
You install RVM by executing a script that you download from its repository in github.
$ curl -L https://get.rvm.io | bash -s stable
If this makes you nervous, you can always download the script first, inspect it, and then run
it.
$ curl -L get.rvm.io >rvm-installer
$ less rvm-installer
$ bash rvm-installer
1. RVM isn’t the only way of managing multiple Ruby installations. You might want to look at rbenv
(https://github.com/sstephenson/rbenv/) or chruby (https://github.com/postmodern/chruby).
2. http://rvm.io/rvm/prerequisites/
Behind the scenes, either option fetches a script from the RVM git repository and executes
it on your local box. The end result is that RVM is installed in a directory named .rvm beneath
your home directory. At the end of the process, RVM spits out a page or so of information.
You should read it.
You may need to knit RVM into your environment. To find out, have a look at the end of
~/.bashrc. If it doesn’t mention RVM, add the following:
source $HOME/.rvm/scripts/rvm
Once that’s done, start a new terminal window (because RVM gets loaded only when your
3
.bashrc file executes). Type rvm help, and you should get a summary of RVM usage.
Before we use RVM to install Ruby, we have to let it install a few things that it will need. To
do that, we need to let RVM install various system libraries and utilities that are used when
building Ruby. First, we have to give it permission to manage packages:
dave@ubuntu:~$ rvm autolibs packages
4
If you run into problems, Wayne has a great set of hints on the RVM installation page.
RVM first installs the system packages it needs (if any). At this stage, you may be prompted
5
to enter a password that gives you superuser privileges.
RVM then downloads the appropriate source code and builds Ruby 2.0. It also installs a few
tools (including irb, RDoc, ri, and RubyGems). Be patient—the process may take five minutes
or so. Once it finishes, you’ll have Ruby 2.0 installed. To use it, type the following:
dave@ubuntu:~$ rvm use 2.0.0
info: Using ruby 2.0.0
dave@ubuntu:~$ ruby -v
ruby 2.0.0p0 (2013-02-24 revision 39474) [i686-linux]
This is probably more work than you were expecting. If all you wanted to do was install a
prepacked Ruby, we’d agree. But what you’ve really done here is given yourself an incredible
amount of flexibility. Maybe in the future a project comes along that requires that you use
Ruby 1.8.7. That’s not a problem—just use rvm install 1.8.7 to install it, and use rvm use 1.8.7
to switch to it.
The rvm use command applies only to the current terminal session. If you want to make it
apply to all your sessions, issue this command:
$ rvm use --default 2.0.0
The RubyGems that you install while you’re using an RVM-installed Ruby will be added to
that version of Ruby and not installed globally. Do not prepend the gem install command
with a sudo—bad things will happen.
The Ruby developers use Subversion (often abbreviated as SVN) as their revision control system, so
you’ll need a Subversion client installed on your machine. Once done, you can use RVM to install the
very latest Ruby using rvm install ruby-head or the latest version of the 2.0 branch using rvm install 2.0-
head.
If you believe that you should have Ruby installed and yet you get an error saying something
like “ruby: command not found,” then it is likely that the Ruby program is not in your path
—the list of places that the shell searches for programs to run. If you used the Windows
One-Click Installer, make sure you rebooted before trying this command. If you’re on Linux
or OS X and you’re using RVM, make sure you type rvm use 2.0 before trying to use Ruby.
Interactive Ruby
One way to run Ruby interactively is simply to type ruby at the shell prompt. Here we typed
in the single puts expression and an end-of-file character (which is Ctrl+D on our system).
6. http://pragprog.com/titles/ruby4/code
7. Remember, you may need to use ruby1.9 as the command name if you installed using a package man-
agement system.
This process works, but it’s painful if you make a typo, and you can’t really see what’s going
on as you type.
$ ruby
puts "Hello, world!"
^D
Hello, world!
For most folks, irb—Interactive Ruby—is the tool of choice for executing Ruby interactively.
irb is a Ruby shell, complete with command-line history, line-editing capabilities, and job
control. (In fact, it has its own chapter: Chapter 18, Interactive Ruby Shell, on page 253.) You
run irb from the command line. Once it starts, just type in Ruby code. It will show you the
value of each expression as it evaluates it. Exit an irb session by typing exit or by using the
Ctrl+D.
$ irb
2.0.0 :001 > def sum(n1, n2)
2.0.0 :002?> n1 + n2
2.0.0 :003?> end
=> nil
2.0.0 :004 > sum(3,4)
=> 7
2.0.0 :005 > sum("cat", "dog")
=> "catdog"
2.0.0 :006 > exit
We recommend that you get familiar with irb so you can try our examples interactively.
Ruby Programs
The normal way to write Ruby programs is to put them in one or more files. You’ll use a
text editor (Emacs, vim, Sublime, and so on) or an IDE (such as NetBeans) to create and
maintain these files. You’ll then run the files either from within the editor or IDE or from
the command line. I personally use both techniques, typically running from within the editor
for single-file programs and from the command line for more complex ones.
Let’s start by creating a simple Ruby program and running it. Open a command window,
and navigate to the pickaxe directory you created earlier:
$ cd ~/pickaxe (unix)
C:\> cd \pickaxe (windows)
Then, using your editor of choice, create the file myprog.rb, containing the following text.
gettingstarted/myprog.rb
puts "Hello, Ruby Programmer"
puts "It is now #{Time.now}"
(Note that the second string contains the text Time.now between curly braces, not parentheses.)
You can run a Ruby program from a file as you would any other shell script, Perl program,
or Python program. Simply run the Ruby interpreter, giving it the script name as an argument:
$ ruby myprog.rb
Hello, Ruby Programmer
It is now 2013-05-27 12:30:36 -0500
If you make this source file executable (using, for instance, chmod +x myprog.rb), Unix lets you
run the file as a program:
$ ./myprog.rb
Hello, Ruby Programmer
It is now 2013-05-27 12:30:36 -0500
You can do something similar under Microsoft Windows using file associations, and you
can run Ruby GUI applications by double-clicking their names in Windows Explorer.
$ ri GC
-----------------------------------------------------------------------------------
The GC module provides an interface to Ruby's garbage collection mechanism. Some of
the underlying methods are also available via the ObjectSpace module.
You may obtain information about the operation of the GC through GC::Profiler.
-----------------------------------------------------------------------------------
Class methods:
count, disable, enable, malloc_allocated_size, malloc_allocations,
start, stat, stress, stress=
Instance methods:
garbage_collect
8. If your system supports it, you can avoid hard-coding the path to Ruby in the “shebang” line by using
#!/usr/bin/env ruby, which will search your path for ruby and then execute it.
9. Including http://www.ruby-doc.org and http://rubydoc.info
10. If you installed Ruby using rvm, there’s one additional step to get ri documentation available. At a
prompt, enter rvm docs generate.
If the method you give ri occurs in more than one class or module, ri will list the alternatives.
$ ri assoc
Implementation from Array
------------------------------------------------------------------------------
ary.assoc(obj) -> new_ary or nil
------------------------------------------------------------------------------
Searches through an array whose elements are also arrays comparing obj
with the first element of each contained array using obj.==.
Returns the first contained array that matches (that is, the first associated
array), or nil if no match is found.
For general help on using ri, type ri --help. In particular, you might want to experiment with
the --format option, which tells ri how to render decorated text (such as section headings). If
your terminal program supports ANSI escape sequences, using --format=ansi will generate a
nice, colorful display. Once you find a set of options you like, you can set them into the RI
environment variable. Using our shell (zsh), this would be done using the following:
$ export RI="--format ansi --width 70"
If a class or module isn’t yet documented in RDoc format, ask the friendly folks over at sug-
gestions@ruby-doc.org to consider adding it.
All this command-line hacking may seem a tad off-putting if you’re not a regular visitor to
the shell prompt. But, in reality, it isn’t that difficult, and the power you get from being able
to string together commands this way is often surprising. Stick with it, and you’ll be well
on your way to mastering both Ruby and your computer.
Ruby.new
Most books on programming languages look about the same. They start with chapters on
basic types: integers, strings, and so on. Then they look at expressions, before moving on to
if and while statements. Then, perhaps around Chapter 7 or 8, they’ll start mentioning classes.
We find that somewhat tedious.
Instead, when we designed this book, we had a grand plan (we were younger then). We
wanted to document the language from the top down, starting with classes and objects and
ending with the nitty-gritty syntax details. It seemed like a good idea at the time. After all,
most everything in Ruby is an object, so it made sense to talk about objects first.
Or so we thought.
Unfortunately, it turns out to be difficult to describe a language that way. If you haven’t
covered strings, if statements, assignments, and other details, it’s difficult to write examples
of classes. Throughout our top-down description, we kept coming across low-level details
we needed to cover so that the example code would make sense.
So, we came up with another grand plan (they don’t call us pragmatic for nothing). We’d
still describe Ruby starting at the top. But before we did that, we’d add a short chapter that
described all the common language features used in the examples along with the special
vocabulary used in Ruby, a kind of mini-tutorial to bootstrap us into the rest of the book.
And that mini-tutorial is this chapter.
(for example, the name of the song) and methods that use that state (perhaps a method to
play the song).
Once you have these classes, you’ll typically want to create a number of instances of each.
For the jukebox system containing a class called Song, you’d have separate instances for
popular hits such as “Ruby Tuesday,” “Enveloped in Python,” “String of Pearls,” “Small
Talk,” and so on. The word object is used interchangeably with class instance (and being lazy
typists, we’ll probably be using the word object more frequently).
In Ruby, these objects are created by calling a constructor, a special method associated with
a class. The standard constructor is called new.
song1 = Song.new("Ruby Tuesday")
song2 = Song.new("Enveloped in Python")
# and so on
These instances are both derived from the same class, but they have unique characteristics.
First, every object has a unique object identifier (abbreviated as object ID). Second, you can
define instance variables, variables with values that are unique to each instance. These instance
variables hold an object’s state. Each of our songs, for example, will probably have an instance
variable that holds the song title.
Within each class, you can define instance methods. Each method is a chunk of functionality
that may be called in the context of the class and (depending on accessibility constraints)
from outside the class. These instance methods in turn have access to the object’s instance
variables and hence to the object’s state. A Song class, for example, might define an instance
method called play. If a variable referenced a particular Song instance, you’d be able to call
that instance’s play method and play that song.
Methods are invoked by sending a message to an object. The message contains the method’s
1
name, along with any parameters the method may need. When an object receives a message,
it looks into its own class for a corresponding method. If found, that method is executed. If
the method isn’t found...well, we’ll get to that later.
This business of methods and messages may sound complicated, but in practice it is very
natural. Let’s look at some method calls. In this code, we’re using puts, a standard Ruby
method that writes its argument(s) to the console, adding a newline after each:
puts "gin joint".length
puts "Rick".index("c")
puts 42.even?
puts sam.play(song)
produces:
9
2
true
duh dum, da dum de dum ...
Each line shows a method being called as an argument to puts. The thing before the period
is called the receiver, and the name after the period is the method to be invoked. The first
example asks a string for its length; the second asks a different string to find the index of the
letter c. The third line asks the number 42 if it is even (the question mark is part of the method
1. This idea of expressing method calls in the form of messages comes from Smalltalk.
name even?). Finally, we ask Sam to play us a song (assuming there’s an existing variable
called sam that references an appropriate object).
It’s worth noting here a major difference between Ruby and most other languages. In (say)
Java, you’d find the absolute value of some number by calling a separate function and
passing in that number. You could write this:
num = Math.abs(num) // Java code
In Ruby, the ability to determine an absolute value is built into numbers—they take care of
the details internally. You simply send the message abs to a number object and let it do the
work:
num = -1234 # => -1234
positive = num.abs # => 1234
The same applies to all Ruby objects. In C you’d write strlen(name), but in Ruby it would be
name.length, and so on. This is part of what we mean when we say that Ruby is a genuine
object-oriented language.
As the example shows, Ruby syntax is clean. You don’t need semicolons at the ends of
statements as long as you put each statement on a separate line. Ruby comments start with
a # character and run to the end of the line. Code layout is pretty much up to you; indentation
is not significant (but using two-character indentation will make you friends in the commu-
nity if you plan on distributing your code).
Methods are defined with the keyword def, followed by the method name (in this case, the
name is say_goodnight) and the method’s parameters between parentheses. (In fact, the
parentheses are optional, but we like to use them.) Ruby doesn’t use braces to delimit the
bodies of compound statements and definitions. Instead, you simply finish the body with
the keyword end. Our method’s body is pretty simple. The first line concatenates the literal
string "Good night," and the parameter name and assigns the result to the local variable result.
The next line returns that result to the caller. Note that we didn’t have to declare the variable
result; it sprang into existence when we assigned to it.
Having defined the method, we invoke it twice. In both cases, we pass the result to the
method puts, which simply outputs its argument followed by a newline (moving on to the
next line of output):
Good night, John-Boy
Good night, Mary-Ellen
The line
puts say_goodnight("John-Boy")
contains two method calls, one to the method say_goodnight and the other to the method puts.
Why does one call have its arguments in parentheses while the other doesn’t? In this case,
it’s purely a matter of taste. The following lines are equivalent:
puts say_goodnight("John-Boy")
puts(say_goodnight("John-Boy"))
However, life isn’t always that simple, and precedence rules can make it difficult to know
which argument goes with which method invocation, so we recommend using parentheses
in all but the simplest cases.
This example also shows some Ruby string objects. Ruby has many ways to create a string
object, but probably the most common is to use string literals, which are sequences of characters
between single or double quotation marks. The difference between the two forms is the
amount of processing Ruby does on the string while constructing the literal. In the single-
quoted case, Ruby does very little. With a few exceptions, what you enter in the string literal
becomes the string’s value.
In the double-quoted case, Ruby does more work. First, it looks for substitutions (sequences
that start with a backslash character) and replaces them with some binary value. The most
common of these is \n, which is replaced with a newline character. When a string containing
a newline is output, that newline becomes a line break:
puts "And good night,\nGrandma"
produces:
And good night,
Grandma
The second thing that Ruby does with double-quoted strings is expression interpolation.
Within the string, the sequence #{expression} is replaced by the value of expression. We could
use this to rewrite our previous method:
def say_goodnight(name)
result = "Good night, #{name}"
return result
end
puts say_goodnight('Pa')
produces:
Good night, Pa
When Ruby constructs this string object, it looks at the current value of name and substitutes
it into the string. Arbitrarily complex expressions are allowed in the #{...} construct. In the
following example, we invoke the capitalize method, defined for all strings, to output our
parameter with a leading uppercase letter:
def say_goodnight(name)
result = "Good night, #{name.capitalize}"
return result
end
puts say_goodnight('uncle')
produces:
Good night, Uncle
For more information on strings, as well as on the other Ruby standard types, see Chapter
6, Standard Types, on page 83.
Finally, we could simplify this method some more. The value returned by a Ruby method
is the value of the last expression evaluated, so we can get rid of the temporary variable and
the return statement altogether. This is idiomatic Ruby.
def say_goodnight(name)
"Good night, #{name.capitalize}"
end
puts say_goodnight('ma')
produces:
Good night, Ma
We promised that this section would be brief. We have just one more topic to cover: Ruby
names. For brevity, we’ll be using some terms (such as class variable) that we aren’t going to
define here. However, by talking about the rules now, you’ll be ahead of the game when we
actually come to discuss class variables and the like later.
Ruby uses a convention that may seem strange at first: the first characters of a name indicate
how the name is used. Local variables, method parameters, and method names should all
2
start with a lowercase letter or an underscore. Global variables are prefixed with a dollar
sign ($), and instance variables begin with an “at” sign (@). Class variables start with two
3
“at” signs (@@). Finally, class names, module names, and constants must start with an
uppercase letter. Samples of different names are given in Table 1, Example variable, class, and
constant names, on page 20.
Following this initial character, a name can be any combination of letters, digits, and
underscores (with the proviso that the character following an @ sign may not be a digit).
However, by convention, multiword instance variables are written with underscores between
the words, and multiword class names are written in MixedCase (with each word capitalized).
Method names may end with the characters ?, !, and =.
2. If your source files use non-ASCII characters (for example, because they’re written in UTF-8 encoding),
all non-ASCII characters are assumed to be lowercase letters.
3. Although we talk about global and class variables here for completeness, you’ll find they are rarely
used in Ruby programs. There’s a lot of evidence that global variables make programs harder to
maintain. Class variables are not as dangerous—it’s just that people tend not to use them much.
You may have noticed that we used the special value nil in this example. In many languages,
the concept of nil (or null) means “no object.” In Ruby, that’s not the case; nil is an object, just
like any other, that happens to represent nothing. Anyway, let’s get back to arrays and
hashes.
Sometimes creating arrays of words can be a pain, what with all the quotes and commas.
Fortunately, Ruby has a shortcut; %w does just what we want:
a = [ 'ant', 'bee', 'cat', 'dog', 'elk' ]
a[0] # => "ant"
a[3] # => "dog"
# this is the same:
a = %w{ ant bee cat dog elk }
a[0] # => "ant"
a[3] # => "dog"
Ruby hashes are similar to arrays. A hash literal uses braces rather than square brackets.
The literal must supply two objects for every entry: one for the key, the other for the value.
The key and value are normally separated by =>.
For example, you could use a hash to map musical instruments to their orchestral sections.
inst_section = {
'cello' => 'string',
'clarinet' => 'woodwind',
'drum' => 'percussion',
'oboe' => 'woodwind',
'trumpet' => 'brass',
'violin' => 'string'
}
The thing to the left of the => is the key, and the thing to the right is the corresponding value.
Keys in a particular hash must be unique; you can’t have two entries for “drum.” The keys
and values in a hash can be arbitrary objects. You can have hashes where the values are
arrays, other hashes, and so on.
Hashes are indexed using the same square bracket notation as arrays. In this code, we’ll use
the p method to write the values to the console. This works like puts but displays values such
as nil explicitly.
p inst_section['oboe']
p inst_section['cello']
p inst_section['bassoon']
produces:
"woodwind"
"string"
nil
As the previous example shows, a hash by default returns nil when indexed by a key it doesn’t
contain. Normally this is convenient, because nil means false when used in conditional
expressions. Sometimes you’ll want to change this default. For example, if you’re using a
hash to count the number of times each different word occurs in a file, it’s convenient to
have the default value be zero. Then you can use the word as the key and simply increment
the corresponding hash value without worrying about whether you’ve seen that word before.
This is easily done by specifying a default value when you create a new, empty hash. (Have
a look at the full source for the word frequency counter on page 49.)
histogram = Hash.new(0) # The default value is zero
histogram['ruby'] # => 0
histogram['ruby'] = histogram['ruby'] + 1
histogram['ruby'] # => 1
Array and hash objects have many useful methods; see the discussion on page 45, as well
as the reference sections for arrays on page 421 and for hashes on page 521.
2.4 Symbols
Often, when programming, you need to create a name for something significant. For example,
you might want to refer to the compass points by name, so you’d write this:
NORTH = 1
EAST = 2
SOUTH = 3
WEST = 4
Then, in the rest of your code, you could use the constants instead of the numbers:
walk(NORTH)
look(EAST)
Most of the time, the actual numeric values of these constants are irrelevant (as long as they
are unique). All you want to do is differentiate the four directions.
Ruby offers a cleaner alternative. Symbols are simply constant names that you don’t have to
predeclare and that are guaranteed to be unique. A symbol literal starts with a colon and is
normally followed by some kind of name:
walk(:north)
look(:east)
There’s no need to assign some kind of value to a symbol—Ruby takes care of that for you.
Ruby also guarantees that no matter where it appears in your program, a particular symbol
will have the same value. That is, you can write the following:
def walk(direction)
if direction == :north
# ...
end
end
Symbols are frequently used as keys in hashes. We could write our previous example as
this:
inst_section = {
:cello => 'string',
:clarinet => 'woodwind',
:drum => 'percussion',
:oboe => 'woodwind',
:trumpet => 'brass',
:violin => 'string'
}
inst_section[:oboe] # => "woodwind"
inst_section[:cello] # => "string"
# Note that strings aren't the same as symbols...
inst_section['cello'] # => nil
In fact, symbols are so frequently used as hash keys that Ruby has a shortcut syntax: you
can use name: value pairs to create a hash if the keys are symbols:
inst_section = {
cello: 'string',
clarinet: 'woodwind',
drum: 'percussion',
oboe: 'woodwind',
trumpet: 'brass',
violin: 'string'
}
puts "An oboe is a #{inst_section[:oboe]} instrument"
produces:
An oboe is a woodwind instrument
if today.saturday?
puts "Do chores around the house"
elsif today.sunday?
puts "Relax"
else
puts "Go to work"
end
produces:
Go to work
Most statements in Ruby return a value, which means you can use them as conditions. For
example, the kernel method gets returns the next line from the standard input stream or nil
when the end of the file is reached. Because Ruby treats nil as a false value in conditions, you
could write the following to process the lines in a file:
while line = gets
puts line.downcase
end
Here, the assignment statement sets the variable line to either the next line of text or nil, and
then the while statement tests the value of the assignment, terminating the loop when it is nil.
Ruby statement modifiers are a useful shortcut if the body of an if or while statement is just a
single expression. Simply write the expression, followed by if or while and the condition. For
example, here’s a simple if statement:
if radiation > 3000
puts "Danger, Will Robinson"
end
The forward slashes delimit the pattern, which consists of the two things we’re matching,
separated by a pipe character (|). This pipe character means “either the thing on the right or
the thing on the left,” in this case either Perl or Python. You can use parentheses within pat-
terns, just as you can in arithmetic expressions, so you could also have written this pattern
like this:
/P(erl|ython)/
You can also specify repetition within patterns. /ab+c/ matches a string containing an a followed
by one or more b’s, followed by a c. Change the plus to an asterisk, and /ab*c/ creates a regular
expression that matches one a, zero or more b’s, and one c.
You can also match one of a group of characters within a pattern. Some common examples
are character classes such as \s, which matches a whitespace character (space, tab, newline,
and so on); \d, which matches any digit; and \w, which matches any character that may appear
in a typical word. A dot (.) matches (almost) any character. A table of these character classes
appears in Table 2, Character class abbreviations, on page 101.
We can put all this together to produce some useful regular expressions:
/\d\d:\d\d:\d\d/ # a time such as 12:34:56
/Perl.*Python/ # Perl, zero or more other chars, then Python
/Perl Python/ # Perl, a space, and Python
/Perl *Python/ # Perl, zero or more spaces, and Python
/Perl +Python/ # Perl, one or more spaces, and Python
/Perl\s+Python/ # Perl, whitespace characters, then Python
/Ruby (Perl|Python)/ # Ruby, a space, and either Perl or Python
Once you have created a pattern, it seems a shame not to use it. The match operator =~ can
be used to match a string against a regular expression. If the pattern is found in the string,
=~ returns its starting position; otherwise, it returns nil. This means you can use regular
expressions as the condition in if and while statements. For example, the following code
fragment writes a message if a string contains the text Perl or Python:
line = gets
if line =~ /Perl|Python/
puts "Scripting language mentioned: #{line}"
end
The part of a string matched by a regular expression can be replaced with different text using
one of Ruby’s substitution methods:
line = gets
newline = line.sub(/Perl/, 'Ruby') # replace first 'Perl' with 'Ruby'
newerline = newline.gsub(/Python/, 'Ruby') # replace every 'Python' with 'Ruby'
You can replace every occurrence of Perl and Python with Ruby using this:
line = gets
newline = line.gsub(/Perl|Python/, 'Ruby')
We’ll have a lot more to say about regular expressions as we go through the book.
Why are there two kinds of delimiter? It’s partly because sometimes one feels more natural
to write than another. It’s partly too because they have different precedences: the braces
bind more tightly than the do/end pairs. In this book, we try to follow what is becoming a
Ruby standard and use braces for single-line blocks and do/end for multiline blocks.
All you can do with a block is associate it with a call to a method. You do this by putting the
start of the block at the end of the source line containing the method call.
For example, in the following code, the block containing puts "Hi" is associated with the call
to the method greet (which we don’t show):
greet { puts "Hi" }
A method can then invoke an associated block one or more times using the Ruby yield
statement. You can think of yield as being something like a method call that invokes the block
associated with the call to the method containing the yield.
The following example shows this in action. We define a method that calls yield twice. We
then call this method, putting a block on the same line, after the call (and after any arguments
4
to the method).
def call_block
puts "Start of method"
yield
yield
puts "End of method"
end
The code in the block (puts "In the block") is executed twice, once for each call to yield.
You can provide arguments to the call to yield, and they will be passed to the block. Within
the block, you list the names of the parameters to receive these arguments between vertical
bars (|params...|). The following example shows a method calling its associated block twice,
passing the block two arguments each time:
4. Some people like to think of the association of a block with a method as a kind of argument passing.
This works on one level, but it isn’t really the whole story. You may be better off thinking of the block
and the method as coroutines, which transfer control back and forth between themselves.
This is a very harmless bird, about the size of the small Sparrow-
Hawk, of a dark colour, and with a large mouth. They never go out
till the evening, and then catch beetles and other insects for their
sustenance.
THE
RAVEN.
This is the largest bird that feeds on carrion, and is of a fine shining
colour; in some places it is very serviceable, in eating up the stinking
flesh or carcases of dead beasts and other carrion, but in many other
places very mischievous, and does a great deal of harm. I having been
allowed as much per head for killing them as I had for kites and
hawks, as they are equally pernicious in killing and devouring young
rabbits, ducklings and chickens.
I know of no better way to catch them, where they become
troublesome, than to set two traps for them, in the same manner as
you do for the buzzard, [see plate VI. fig. 1.] and put a rat between
them for a bait, but when you have taken one or two, you must move
your traps to another place, or the others will prove too shy to be
caught; for as soon as one is taken, great numbers will keep round
him, and seeing him fast, will grow suspicious of some danger, and
not come near the place any more; but by observing the above
method, in moving the traps, I have caught great numbers of them in
a day, though it is attended with some labour and trouble.
I have often caught the London Ravens near twenty miles from
home, in warrens, where they will sometimes come after the young
Rabbits; by the London Ravens I mean those that generally frequent
the outskirts of the metropolis, and live upon the filth lying there,
grubbing up the dirt in order to get at their food, from whence the
tops of their wings become of a nasty, dusky brown colour,
occasioned by their wallowing in the dirt, by which means they are
easily distinguishable from the country Ravens, which are as black as
jet, according to the old saying, As black as a Raven.
I have seen some of these Ravens sit upon a lamb, that has been
dropped weak, not being able to run, when they have got to his head
and picked out the creature’s eyes while yet alive. Another remark I
shall make, which is to point out the difference between the manner
of birds of the hawk kind carrying their prey, and those of the carrion
kind. Now it is observable that buzzards, kites, hawks and owls,
constantly carry their prey in their claws, whereas Ravens, carrion-
crows and magpies carry their food in their beaks.
THE
CARRION
CROW.
FINIS.
TRANSCRIBER’S NOTES
Typos fixed; non-standard spelling and dialect
retained.
Used numbers for footnotes.
The original did not include Plate II.
*** END OF THE PROJECT GUTENBERG EBOOK THE UNIVERSAL
DIRECTORY FOR TAKING ALIVE AND DESTROYING RATS, ***
1.D. The copyright laws of the place where you are located also
govern what you can do with this work. Copyright laws in most
countries are in a constant state of change. If you are outside
the United States, check the laws of your country in addition to
the terms of this agreement before downloading, copying,
displaying, performing, distributing or creating derivative works
based on this work or any other Project Gutenberg™ work. The
Foundation makes no representations concerning the copyright
status of any work in any country other than the United States.
1.E.6. You may convert to and distribute this work in any binary,
compressed, marked up, nonproprietary or proprietary form,
including any word processing or hypertext form. However, if
you provide access to or distribute copies of a Project
Gutenberg™ work in a format other than “Plain Vanilla ASCII” or
other format used in the official version posted on the official
Project Gutenberg™ website (www.gutenberg.org), you must,
at no additional cost, fee or expense to the user, provide a copy,
a means of exporting a copy, or a means of obtaining a copy
upon request, of the work in its original “Plain Vanilla ASCII” or
other form. Any alternate format must include the full Project
Gutenberg™ License as specified in paragraph 1.E.1.
• You pay a royalty fee of 20% of the gross profits you derive
from the use of Project Gutenberg™ works calculated using the
method you already use to calculate your applicable taxes. The
fee is owed to the owner of the Project Gutenberg™ trademark,
but he has agreed to donate royalties under this paragraph to
the Project Gutenberg Literary Archive Foundation. Royalty
payments must be paid within 60 days following each date on
which you prepare (or are legally required to prepare) your
periodic tax returns. Royalty payments should be clearly marked
as such and sent to the Project Gutenberg Literary Archive
Foundation at the address specified in Section 4, “Information
about donations to the Project Gutenberg Literary Archive
Foundation.”
• You comply with all other terms of this agreement for free
distribution of Project Gutenberg™ works.
1.F.
Most people start at our website which has the main PG search
facility: www.gutenberg.org.
Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.
ebookfinal.com