Tải bản đầy đủ (.pdf) (990 trang)

Tài liệu tự học lập trình - ruby cookbook recipes for object oriented scripting (2nd ed ) carlson richardson 2015 03 25

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (9.05 MB, 990 trang )

1
on 2.
i t i by
Ed Ru
d for
2 n te d

Up

da

Ruby Cookbook

Recipes cover:
■■

Data structures including strings, numbers, date and time,
arrays, hashes, files, and directories

■■

Using Ruby’s code blocks, also known as closures

■■

OOP features such as classes, methods, objects, and modules

■■

XML and HTML, databases and persistence, and graphics and
other formats



■■

Web development with Rails and Sinatra

■■

Internet services, web services, and distributed programming

■■

Software testing, debugging, packaging, and distributing

■■

Multitasking, multithreading, and extending Ruby with other
languages

tax alone, but by every
line of concrete code
they write. To that end,
this book is filled with
practical recipes, tips,
knowledge, and wisdom.
I hope it leads readers
to the next step of Ruby
programming.




—Yukihiro (Matz) Matsumoto

Creator of Ruby

Lucas Carlson founded AppFog, a PaaS that leverages the open source Cloud
Foundry project. A professional developer for 20 years, he specializes in Ruby on
Rails development. Lucas has written Programming for PaaS and Ruby Cookbook,
First Edition (both O’Reilly). He maintains a website at />Leonard Richardson has been programming since he was eight years old.
Recently, the quality of his code has improved somewhat. He is responsible for
programming language libraries, including Rubyful Soup. He maintains a website
at />PROGR AMMING L ANGUAGES/RUBY

US $49.99

CAN $57.99

ISBN: 978-1-449-37371-9

Twitter: @oreillymedia
facebook.com/oreilly

Ruby

Carlson &
Richardson

Revised for Ruby 2.1, each recipe includes a discussion on why and how
the solution works. You’ll find recipes suitable for all skill levels, from
Ruby newbies to experts who need an occasional reference. With Ruby
Cookbook, you’ll not only save time, but keep your brain percolating with

new ideas as well.

“Programmers
live by languagedon’tsyn-

SECOND EDITION

Ruby Cookbook

Why spend time on coding problems that others have already solved when
you could be making real progress on your Ruby project? This updated
cookbook provides more than 350 recipes for solving common problems,
on topics ranging from basic data structures, classes, and objects, to web
development, distributed programming, and multithreading.

RECIPES FOR OBJEC T-ORIENTED SCRIPTING

Cookbook
Lucas Carlson
& Leonard Richardson
www.it-ebooks.info


1
on 2.
i t i by
Ed Ru
d for
2 n te d


Up

da

Ruby Cookbook

Recipes cover:
■■

Data structures including strings, numbers, date and time,
arrays, hashes, files, and directories

■■

Using Ruby’s code blocks, also known as closures

■■

OOP features such as classes, methods, objects, and modules

■■

XML and HTML, databases and persistence, and graphics and
other formats

■■

Web development with Rails and Sinatra

■■


Internet services, web services, and distributed programming

■■

Software testing, debugging, packaging, and distributing

■■

Multitasking, multithreading, and extending Ruby with other
languages

tax alone, but by every
line of concrete code
they write. To that end,
this book is filled with
practical recipes, tips,
knowledge, and wisdom.
I hope it leads readers
to the next step of Ruby
programming.



—Yukihiro (Matz) Matsumoto

Creator of Ruby

Lucas Carlson founded AppFog, a PaaS that leverages the open source Cloud
Foundry project. A professional developer for 20 years, he specializes in Ruby on

Rails development. Lucas has written Programming for PaaS and Ruby Cookbook,
First Edition (both O’Reilly). He maintains a website at />Leonard Richardson has been programming since he was eight years old.
Recently, the quality of his code has improved somewhat. He is responsible for
programming language libraries, including Rubyful Soup. He maintains a website
at />PROGR AMMING L ANGUAGES/RUBY

US $49.99

Twitter: @oreillymedia
facebook.com/oreilly

Ruby

Carlson &
Richardson

Revised for Ruby 2.1, each recipe includes a discussion on why and how
the solution works. You’ll find recipes suitable for all skill levels, from
Ruby newbies to experts who need an occasional reference. With Ruby
Cookbook, you’ll not only save time, but keep your brain percolating with
new ideas as well.

“Programmers
live by languagedon’tsyn-

SECOND EDITION

Ruby Cookbook

Why spend time on coding problems that others have already solved when

you could be making real progress on your Ruby project? This updated
cookbook provides more than 350 recipes for solving common problems,
on topics ranging from basic data structures, classes, and objects, to web
development, distributed programming, and multithreading.

RECIPES FOR OBJEC T-ORIENTED SCRIPTING

Cookbook
Lucas Carlson
& Leonard Richardson

CAN $57.99

ISBN: 978-1-449-37371-9

www.it-ebooks.info


SECOND EDITION

Ruby Cookbook

Lucas Carlson and Leonard Richardson

www.it-ebooks.info


Ruby Cookbook
by Lucas Carlson and Leonard Richardson
Copyright © 2015 Lucas Carlson and Leonard Richardson. All rights reserved.

Printed in the United States of America.
Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.
O’Reilly books may be purchased for educational, business, or sales promotional use. Online editions are
also available for most titles (). For more information, contact our corporate/
institutional sales department: 800-998-9938 or

Editors: Brian Anderson and Allyson MacDonald
Production Editor: Matthew Hacker
Proofreader: Rachel Monaghan
Indexer: Angela Howard
July 2006:
March 2015:

Interior Designer: David Futato
Cover Designer: Ellie Volckhausen
Illustrator: Rebecca Demarest

First Edition
Second Edition

Revision History for the Second Edition
2015-03-10: First Release
See for release details.
The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Ruby Cookbook, the cover image of a
side-striped jackal, and related trade dress are trademarks of O’Reilly Media, Inc.
While the publisher and the authors have used good faith efforts to ensure that the information and
instructions contained in this work are accurate, the publisher and the authors disclaim all responsibility
for errors or omissions, including without limitation responsibility for damages resulting from the use of
or reliance on this work. Use of the information and instructions contained in this work is at your own
risk. If any code samples or other technology this work contains or describes is subject to open source

licenses or the intellectual property rights of others, it is your responsibility to ensure that your use
thereof complies with such licenses and/or rights.

978-1-449-37371-9
[M]

www.it-ebooks.info


For Yoscelina, my muse and inspiration for everything great I have ever accomplished.
For Hugh and Valentina, the most incredible miracles ever.
For Tess, who sat by me the whole time.
—Lucas Carlson
For Sumana.
—Leonard Richardson

www.it-ebooks.info


www.it-ebooks.info


Table of Contents

Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii
1. Ruby 2.1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 What’s Different Between Ruby 1.8 and 2.1?
1.2 YARV (Yet Another Ruby VM) Bytecode Interpreter
1.3 Syntax Changes
1.4 Keyword Arguments

1.5 Performance Enhancements
1.6 Refinements
1.7 Debugging with DTrace and TracePoint
1.8 Module Prepending
1.9 New Methods
1.10 New Classes
1.11 New Standard Libraries
1.12 What’s Next?

2
9
11
14
15
16
17
19
21
23
26
27

2. Strings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.1 Building a String from Parts
2.2 Substituting Variables into Strings
2.3 Substituting Variables into an Existing String
2.4 Reversing a String by Words or Characters
2.5 Representing Unprintable Characters
2.6 Converting Between Characters and Values
2.7 Converting Between Strings and Symbols

2.8 Processing a String One Character at a Time
2.9 Processing a String One Word at a Time
2.10 Changing the Case of a String
2.11 Managing Whitespace

33
35
37
39
40
43
44
45
47
49
50
v

www.it-ebooks.info


2.12 Testing Whether an Object Is String-Like
2.13 Getting the Parts of a String You Want
2.14 Word-Wrapping Lines of Text
2.15 Generating a Succession of Strings
2.16 Matching Strings with Regular Expressions
2.17 Replacing Multiple Patterns in a Single Pass
2.18 Validating an Email Address
2.19 Classifying Text with a Bayesian Analyzer


52
53
54
56
59
61
63
66

3. Numbers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
3.1 Parsing a Number from a String
3.2 Comparing Floating-Point Numbers
3.3 Representing Numbers to Arbitrary Precision
3.4 Representing Rational Numbers
3.5 Generating Random Numbers
3.6 Converting Between Numeric Bases
3.7 Taking Logarithms
3.8 Finding Mean, Median, and Mode
3.9 Converting Between Degrees and Radians
3.10 Multiplying Matrices
3.11 Solving a System of Linear Equations
3.12 Using Complex Numbers
3.13 Simulating a Subclass of Fixnum
3.14 Doing Math with Roman Numbers
3.15 Generating a Sequence of Numbers
3.16 Generating Prime Numbers
3.17 Checking a Credit Card Checksum

70
73

76
79
80
82
83
86
89
90
94
97
99
103
109
112
116

4. Date and Time. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
4.1 Finding Today’s Date
4.2 Parsing Dates, Precisely or Fuzzily
4.3 Printing a Date
4.4 Iterating Over Dates
4.5 Doing Date Arithmetic
4.6 Counting the Days Since an Arbitrary Date
4.7 Converting Between Time Zones
4.8 Checking Whether Daylight Saving Time Is in Effect
4.9 Converting Between Time and DateTime Objects
4.10 Finding the Day of the Week
4.11 Handling Commercial Dates
4.12 Running a Code Block Periodically
4.13 Waiting a Certain Amount of Time


vi

|

Table of Contents

www.it-ebooks.info

122
126
129
134
135
138
140
142
144
147
149
150
152


4.14 Adding a Timeout to a Long-Running Operation

155

5. Arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
5.1 Iterating Over an Array

5.2 Rearranging Values Without Using Temporary Variables
5.3 Stripping Duplicate Elements from an Array
5.4 Reversing an Array
5.5 Sorting an Array
5.6 Ignoring Case When Sorting Strings
5.7 Making Sure a Sorted Array Stays Sorted
5.8 Summing the Items of an Array
5.9 Sorting an Array by Frequency of Appearance
5.10 Shuffling an Array
5.11 Getting the N Smallest Items of an Array
5.12 Building a Hash from an Array
5.13 Extracting Portions of Arrays
5.14 Computing Set Operations on Arrays
5.15 Partitioning or Classifying a Set

159
163
165
166
167
169
170
175
177
179
180
183
185
188
191


6. Hashes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
6.1 Using Symbols as Hash Keys
6.2 Creating a Hash with a Default Value
6.3 Adding Elements to a Hash
6.4 Removing Elements from a Hash
6.5 Using an Array or Other Modifiable Object as a Hash Key
6.6 Keeping Multiple Values for the Same Hash Key
6.7 Iterating Over a Hash
6.8 Iterating Over a Hash in Insertion Order
6.9 Printing a Hash
6.10 Inverting a Hash
6.11 Choosing Randomly from a Weighted List
6.12 Building a Histogram
6.13 Remapping the Keys and Values of a Hash
6.14 Extracting Portions of Hashes
6.15 Searching a Hash with Regular Expressions

200
201
203
205
206
209
210
213
214
216
217
220

222
223
224

7. Files and Directories. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
7.1 Checking to See If a File Exists
7.2 Checking Your Access to a File
7.3 Changing the Permissions on a File
7.4 Seeing When a File Was Last Used
7.5 Listing a Directory

230
232
234
237
239

Table of Contents

www.it-ebooks.info

|

vii


7.6 Reading the Contents of a File
7.7 Writing to a File
7.8 Writing to a Temporary File
7.9 Picking a Random Line from a File

7.10 Comparing Two Files
7.11 Performing Random Access on “Read-Once” Input Streams
7.12 Walking a Directory Tree
7.13 Locking a File
7.14 Backing Up to Versioned Filenames
7.15 Pretending a String Is a File
7.16 Redirecting Standard Input or Output
7.17 Processing a Binary File
7.18 Deleting a File
7.19 Truncating a File
7.20 Finding the Files You Want
7.21 Finding and Changing the Current Working Directory

242
246
247
249
250
254
256
259
262
265
268
270
274
275
277
279


8. Code Blocks and Iteration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
8.1 Creating and Invoking a Block
8.2 Writing a Method That Accepts a Block
8.3 Binding a Block Argument to a Variable
8.4 Blocks as Closures: Using Outside Variables Within a Code Block
8.5 Writing an Iterator Over a Data Structure
8.6 Changing the Way an Object Iterates
8.7 Writing Block Methods That Classify or Collect
8.8 Stopping an Iteration
8.9 Looping Through Multiple Iterables in Parallel
8.10 Hiding Setup and Cleanup in a Block Method
8.11 Coupling Systems Loosely with Callbacks

284
286
289
291
293
296
298
300
302
306
308

9. Objects and Classes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
9.1 Managing Instance Data
9.2 Managing Class Data
9.3 Checking Class or Module Membership
9.4 Writing an Inherited Class

9.5 Overloading Methods
9.6 Validating and Modifying Attribute Values
9.7 Defining a Virtual Attribute
9.8 Delegating Method Calls to Another Object
9.9 Converting and Coercing Objects to Different Types
9.10 Getting a Human-Readable Printout of Any Object
9.11 Accepting or Passing a Variable Number of Arguments

viii

|

Table of Contents

www.it-ebooks.info

316
318
321
323
326
328
330
331
334
339
341


9.12 Using Keyword Arguments

9.13 Calling a Superclass’s Method
9.14 Creating an Abstract Method
9.15 Freezing an Object to Prevent Changes
9.16 Making a Copy of an Object
9.17 Declaring Constants
9.18 Implementing Class and Singleton Methods
9.19 Controlling Access by Making Methods Private

343
345
347
350
353
356
358
360

10. Modules and Namespaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
10.1 Simulating Multiple Inheritance with Mixins
10.2 Extending Specific Objects with Modules
10.3 Mixing in Class Methods
10.4 Implementing Enumerable: Write One Method, Get 48 Free
10.5 Avoiding Naming Collisions with Namespaces
10.6 Automatically Loading Libraries as Needed
10.7 Including Namespaces
10.8 Initializing Instance Variables Defined by a Module
10.9 Automatically Initializing Mixed-in Modules
10.10 Prepending Modules

366

370
372
373
377
378
380
382
383
386

11. Reflection and Metaprogramming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
11.1 Finding an Object’s Class and Superclass
11.2 Listing an Object’s Methods
11.3 Listing Methods Unique to an Object
11.4 Getting a Reference to a Method
11.5 Fixing Bugs in Someone Else’s Class
11.6 Listening for Changes to a Class
11.7 Checking Whether an Object Has Necessary Attributes
11.8 Responding to Calls to Undefined Methods
11.9 Automatically Initializing Instance Variables
11.10 Avoiding Boilerplate Code with Metaprogramming
11.11 Metaprogramming with String Evaluations
11.12 Evaluating Code in an Earlier Context
11.13 Undefining a Method
11.14 Aliasing Methods
11.15 Doing Aspect-Oriented Programming
11.16 Enforcing Software Contracts

390
391

394
396
398
400
403
404
409
410
413
415
417
420
423
425

12. XML and HTML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
12.1 Checking That XML Is Well Formed
12.2 Extracting Data from a Document’s Tree Structure

432
434

Table of Contents

www.it-ebooks.info

|

ix



12.3 Extracting Data While Parsing a Document
12.4 Navigating a Document with XPath
12.5 Converting an XML Document into a Hash
12.6 Validating an XML Document
12.7 Substituting XML Entities
12.8 Creating and Modifying XML Documents
12.9 Compressing Whitespace in an XML Document
12.10 Guessing a Document’s Encoding
12.11 Converting from One Encoding to Another
12.12 Extracting All the URLs from an HTML Document
12.13 Transforming Plain Text to HTML
12.14 Converting HTML Documents from the Web into Text
12.15 Creating a Simple Feed Aggregator

436
438
441
444
445
448
452
453
454
456
459
460
463

13. Graphics and Other File Formats. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469

13.1 Thumbnailing Images
13.2 Adding Text to an Image
13.3 Converting One Image Format to Another
13.4 Graphing Data
13.5 Adding Graphical Context with Sparklines
13.6 Symmetrically Encrypting Data
13.7 Parsing Comma-Separated Data
13.8 Parsing Not-Quite-Comma-Separated Data
13.9 Generating and Parsing Excel Spreadsheets
13.10 Compressing and Archiving Files with Gzip and Tar
13.11 Reading and Writing ZIP Files
13.12 Reading and Writing Configuration Files
13.13 Generating PDF Files
13.14 Representing Data as MIDI Music

470
473
476
479
482
485
487
489
490
492
495
497
499
503


14. Databases and Persistence. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
14.1 Serializing Data with YAML
14.2 Serializing Data with Marshal
14.3 Persisting Objects with Madeleine
14.4 Indexing Unstructured Text with SimpleSearch
14.5 Indexing Structured Text with Ferret
14.6 Using Berkeley DB Databases
14.7 Controlling MySQL on Unix
14.8 Finding the Number of Rows Returned by a Query
14.9 Talking Directly to a MySQL Database
14.10 Talking Directly to a PostgreSQL Database
14.11 Using Object Relational Mapping with ActiveRecord

x

|

Table of Contents

www.it-ebooks.info

511
514
515
518
520
524
525
526
528

531
534


14.12 Building Queries Programmatically
14.13 Validating Data with ActiveRecord
14.14 Preventing SQL Injection Attacks
14.15 Using Transactions in ActiveRecord
14.16 Adding Hooks to Table Events
14.17 Adding Taggability with a Database Mixin

538
542
544
547
549
551

15. Internet Services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555
15.1 Grabbing the Contents of a Web Page
15.2 Making an HTTPS Web Request
15.3 Customizing HTTP Request Headers
15.4 Performing DNS Queries
15.5 Sending Mail
15.6 Reading Mail with IMAP
15.7 Reading Mail with POP3
15.8 Being an FTP Client
15.9 Being a Telnet Client
15.10 Being an SSH Client
15.11 Copying a File to Another Machine

15.12 Being a BitTorrent Client
15.13 Pinging a Machine
15.14 Writing an Internet Server
15.15 Parsing URLs
15.16 Writing a CGI Script
15.17 Setting Cookies and Other HTTP Response Headers
15.18 Handling File Uploads via CGI
15.19 Running Servlets with WEBrick
15.20 Creating a Real-World HTTP Client

556
559
561
563
565
569
574
577
579
583
585
587
588
589
592
595
598
600
603
609


16. Web Development: Ruby on Rails. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 613
16.1 Writing a Simple Rails Application to Show System Status
16.2 Passing Data from the Controller to the View
16.3 Creating a Layout for Your Header and Footer
16.4 Redirecting to a Different Location
16.5 Displaying Templates with Render
16.6 Integrating a Database with Your Rails Application
16.7 Understanding Pluralization Rules
16.8 Creating a Login System
16.9 Storing Hashed User Passwords in the Database
16.10 Escaping HTML and JavaScript for Display
16.11 Setting and Retrieving Session Information
16.12 Setting and Retrieving Cookies

616
619
621
624
626
629
633
636
640
642
643
645

Table of Contents


www.it-ebooks.info

|

xi


16.13 Extracting Code into Helper Functions
16.14 Refactoring the View into Partial Snippets of Views
16.15 Adding Dynamic Effects with script.aculo.us
16.16 Generating Forms for Manipulating Model Objects
16.17 Creating an Ajax Form
16.18 Exposing Web Services on Your Website
16.19 Sending Mail with Rails
16.20 Automatically Sending Error Messages to Your Email
16.21 Documenting Your Website
16.22 Unit-Testing Your Website
16.23 Using breakpoint in Your Web Application

647
649
653
655
660
664
666
669
671
672
676


17. Web Development: Sinatra. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 679
17.1 Developing a Minimalistic Web-Services–Based Application
17.2 Writing a Simple Sinatra Application to Show System Status
17.3 Creating a Layout for Your Header and Footer
17.4 Passing Data from the Controller to the View
17.5 Redirecting to a Different Location
17.6 Integrating a Database with Your Sinatra Application
17.7 Setting Status Codes and Headers
17.8 Setting and Retrieving Session Information
17.9 Setting and Retrieving Cookies
17.10 Sending Mail with Sinatra
17.11 Building RESTful Web Services on Your Website
17.12 Creating RESTful JavaScript Clients for Your Web Services

680
681
682
683
685
686
688
688
690
691
692
695

18. Web Services and Distributed Programming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697
18.1 Searching for Books on Amazon

18.2 Finding Photos on Flickr
18.3 Writing an XML-RPC Client
18.4 Writing a SOAP Client
18.5 Writing a SOAP Server
18.6 Charging a Credit Card
18.7 Finding the Cost to Ship Packages via UPS or FedEx
18.8 Sharing a Hash Between Any Number of Computers
18.9 Implementing a Distributed Queue
18.10 Creating a Shared “Whiteboard”
18.11 Securing DRb Services with Access Control Lists
18.12 Automatically Discovering DRb Services with Rinda
18.13 Proxying Objects That Can’t Be Distributed
18.14 Storing Data on Distributed RAM with MemCached
18.15 Caching Expensive Results with MemCached

xii

|

Table of Contents

www.it-ebooks.info

699
702
705
707
709
710
712

713
717
719
722
724
726
729
731


18.16 A Remote-Controlled Jukebox

734

19. Testing, Debugging, Optimizing, and Documenting. . . . . . . . . . . . . . . . . . . . . . . . . . . . 741
19.1 Running Code Only in Debug Mode
19.2 Raising an Exception
19.3 Handling an Exception
19.4 Retrying After an Exception
19.5 Adding Logging to Your Application
19.6 Creating and Understanding Tracebacks
19.7 Writing Unit Tests
19.8 Running Unit Tests
19.9 Testing Code That Uses External Resources
19.10 Using debug to Inspect and Change the State of Your Application
19.11 Documenting Your Application
19.12 Profiling Your Application
19.13 Benchmarking Competing Solutions
19.14 Running Multiple Analysis Tools at Once


742
744
746
748
750
752
755
758
761
765
768
772
775
777

20. Packaging and Distributing Software. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 781
20.1 Finding Libraries by Querying Gem Respositories
20.2 Installing and Using a Gem
20.3 Requiring a Specific Version of a Gem
20.4 Uninstalling a Gem
20.5 Reading Documentation for Installed Gems
20.6 Packaging Your Code as a Gem
20.7 Distributing Your Gems
20.8 Installing and Creating Standalone Packages with setup.rb

782
785
787
790
791

792
795
796

21. Automating Tasks with Rake. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801
21.1 Automatically Running Unit Tests
21.2 Automatically Generating Documentation
21.3 Cleaning Up Generated Files
21.4 Automatically Building a Gem
21.5 Gathering Statistics About Your Code
21.6 Publishing Your Documentation
21.7 Running Multiple Tasks in Parallel
21.8 Creating a Generic Project Rakefile

803
805
808
809
811
814
816
817

22. Multitasking and Multithreading. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 825
22.1 Running a Daemon Process on Unix
22.2 Creating a Windows Service
22.3 Doing Two Things at Once with Threads

826
829

833

Table of Contents

www.it-ebooks.info

|

xiii


22.4 Synchronizing Access to an Object
22.5 Terminating a Thread
22.6 Running a Code Block on Many Objects Simultaneously
22.7 Limiting Multithreading with a Thread Pool
22.8 Driving an External Process with popen
22.9 Capturing the Output and Error Streams from a Unix Shell Command
22.10 Controlling a Process on Another Machine
22.11 Avoiding Deadlock

835
838
840
843
846
848
849
851

23. User Interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 855

23.1 Resources
23.2 Getting Input One Line at a Time
23.3 Getting Input One Character at a Time
23.4 Parsing Command-Line Arguments
23.5 Testing Whether a Program Is Running Interactively
23.6 Setting Up and Tearing Down a Curses Program
23.7 Clearing the Screen
23.8 Determining Terminal Size
23.9 Changing Text Color
23.10 Reading a Password
23.11 Allowing Input Editing with Readline
23.12 Making Your Keyboard Lights Blink
23.13 Creating a GUI Application with Tk
23.14 Creating a GUI Application with wxRuby
23.15 Creating a GUI Application with Ruby/GTK
23.16 Using AppleScript to Get User Input

856
857
859
861
864
865
866
868
870
871
872
874
876

880
884
888

24. Extending Ruby with Other Languages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 891
24.1 Writing a C Extension for Ruby
24.2 Using a C Library from Ruby
24.3 Calling a C Library Through SWIG
24.4 Writing Inline C in Your Ruby Code
24.5 Using Java Libraries with JRuby

892
896
899
902
904

25. System Administration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 909
25.1 Scripting an External Program
25.2 Managing Windows Services
25.3 Running Code as Another User
25.4 Running Periodic Tasks Without cron or at
25.5 Deleting Files That Match a Regular Expression
25.6 Renaming Files in Bulk
25.7 Finding Duplicate Files

xiv

|


Table of Contents

www.it-ebooks.info

910
912
913
915
916
919
922


25.8 Automating Backups
25.9 Normalizing Ownership and Permissions in User Directories
25.10 Killing All Processes for a Given User
25.11 Using Puppet for DevOps System Administration

925
926
930
932

Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 935

Table of Contents

www.it-ebooks.info

|


xv


www.it-ebooks.info


Preface

Life Is Short
This is a book of recipes: solutions to common problems, copy-and-paste code snip‐
pets, explanations, examples, and short tutorials.
This book is meant to save you time. Time, as they say, is money, but a span of time is
also a piece of your life. Our lives are better spent creating new things than fighting
our own errors, or trying to solve problems that have already been solved. We present
this book in the hope that the time it saves, distributed across all its readers, will
greatly outweigh the time we spent creating it.
The Ruby programming language is itself a wonderful time-saving tool. It makes you
more productive than other programming languages because you spend more time
making the computer do what you want, and less wrestling with the language. But
there are many ways for a Ruby programmer to spend time without accomplishing
anything, and we’ve encountered them all:
• Time spent writing Ruby implementations of common algorithms.
• Time spent debugging Ruby implementations of common algorithms.
• Time spent discovering and working around Ruby-specific pitfalls.
• Time spent on repetitive tasks (including repetitive programming tasks!) that
could be automated.
• Time spent duplicating work that someone else has already made publicly
available.
• Time spent searching for a library that does x.

• Time spent evaluating and deciding between the many libraries that do x.
• Time spent learning how to use a library because of poor or outdated
documentation.

xvii

www.it-ebooks.info


• Time lost staying away from a useful technology because it seems intimidating.
We, and the many contributors to this book, recall vividly our own wasted hours and
days. We’ve distilled our experiences into this book so that you don’t waste your time
—or at least so you waste it enjoyably on more interesting problems.
Our other goal is to expand your interests. If you come to this book wanting to gener‐
ate algorithmic music with Ruby then, yes, Recipe 13.14 will save you time over start‐
ing from scratch. It’s more likely that you’d never considered the possibility until now.
Every recipe in this book was developed and written with these two goals in mind: to
save you time, and to keep your brain active with new ideas.

Audience
This cookbook is aimed at people who know at least a little bit of Ruby, or who know
a fair amount about programming in general. This isn’t a Ruby tutorial (see “Other
Resources” on page xxv below for some real tutorials), but if you’re already familiar
with a few other programming languages, you should be able to pick up Ruby by
reading through the first 10 chapters of this book and typing in the code listings as
you go.
We’ve included recipes suitable for all skill levels, from those who are just starting out
with Ruby, to experts who need an occasional reference. We focus mainly on generic
programming techniques, but we also cover specific application frameworks (like
Ruby on Rails and GUI libraries) and best practices (like unit testing).

Even if you just plan to use this book as a reference, we recommend that you skim
through it once to get a picture of the problems we solve. This is a big book, but it
doesn’t solve every problem. If you pick it up and you can’t find a solution to your
problem, or one that nudges you in the right direction, then you’ve lost time.
If you skim through this book once beforehand, you’ll get a fair idea of the problems
we cover in this book, and you’ll get a better hit rate. You’ll know when this book can
help you, and when you should consult other books, do a web search, ask a friend, or
get help some other way.

The Structure of This Book
Each of this book’s chapters focuses on a kind of programming or a particular data
type. This overview of the chapters should give you a picture of how we divided up
the recipes. Each chapter also has its own, somewhat lengthier introduction, which
gives a more detailed view of its recipes. At the very least, we recommend you skim
the chapter introductions and the table of contents.

xviii

|

Preface

www.it-ebooks.info


A brand new chapter covers what has changed since Ruby 1.8 when the first version
of this book was released:
• Chapter 1, Ruby 2.1, covers what is new in Ruby 2.1.
The next six chapters cover Ruby’s built-in data structures:
• Chapter 2, Strings, contains recipes for building, processing, and manipulating

strings of text. We devote a few recipes specifically to regular expressions (Recipe
2.16 through Recipe 2.18), but our focus is on Ruby-specific issues, and regular
expressions are a very general tool. If you haven’t encountered them yet, or just
find them intimidating, we recommend you go through an online tutorial or
Mastering Regular Expressions by Jeffrey Friedl (O’Reilly).
• Chapter 3, Numbers, covers the representation of different types of numbers: real
numbers, complex numbers, arbitrary-precision decimals, and so on. It also
includes Ruby implementations of common mathematical and statistical algo‐
rithms, and explains some Ruby quirks you’ll run into if you create your own
numeric types (Recipe 3.13 and Recipe 3.14).
• Chapter 4, Date and Time, covers Ruby’s two interfaces for dealing with time: the
one based on the C time library, which may be familiar to you from other pro‐
gramming languages, and the one implemented in pure Ruby, which is more
idiomatic.
• Chapter 5, Arrays, introduces the array, Ruby’s simplest compound data type.
Many of an array’s methods are actually methods of the Enumerable mixin; this
means you can apply many of these recipes to hashes and other data types. Some
features of Enumerable are covered in this chapter (Recipe 5.4 and Recipe 5.6),
and some are covered in Chapter 8.
• Chapter 6, Hashes, covers the hash, Ruby’s other basic compound data type.
Hashes make it easy to associate objects with names and find them later (hashes
are sometimes called lookup tables or dictionaries, two telling names). It’s easy to
use hashes along with arrays to build deep and complex data structures.
• Chapter 7, Files and Directories, covers techniques for reading, writing, and
manipulating files. Ruby’s file access interface is based on the standard C file
libraries, so it may look familiar to you. This chapter also covers Ruby’s standard
libraries for searching and manipulating the filesystem; many of these recipes
show up again in Chapter 25.
The first six chapters deal with specific algorithmic problems. The next four are more
abstract: they’re about Ruby idiom and philosophy. If you can’t get the Ruby language

itself to do what you want, or you’re having trouble writing Ruby code that looks the
way Ruby “should” look, the recipes in these chapters may help:

Preface

www.it-ebooks.info

|

xix


• Chapter 8, Code Blocks and Iteration, contains recipes that explore the possibili‐
ties of Ruby’s code blocks (also known as closures).
• Chapter 9, Objects and Classes, covers Ruby’s take on object-oriented program‐
ming. It contains recipes for writing different types of classes and methods, and a
few recipes that demonstrate capabilities of all Ruby objects (such as freezing and
cloning).
• Chapter 10, Modules and Namespaces, covers Ruby’s modules. These constructs
are used to “mix” new behavior into existing classes and to segregate functional‐
ity into different namespaces.
• Chapter 11, Reflection and Metaprogramming, covers techniques for programati‐
cally exploring and modifying Ruby class definitions.
Chapter 7 covers basic file access, but doesn’t touch much on specific file formats. We
devote three chapters to popular ways of storing data:
• Chapter 12, XML and HTML, shows how to handle the most popular data inter‐
change formats. The chapter deals mostly with parsing other people’s XML docu‐
ments and web pages (but see Recipe 12.8).
• Chapter 13, Graphics and Other File Formats, covers data interchange formats
other than XML and HTML, with a special focus on generating and manipulat‐

ing graphics.
• Chapter 14, Databases and Persistence, covers the best Ruby interfaces to data
storage formats, whether you’re serializing Ruby objects to disk, or storing struc‐
tured data in a database. This chapter demonstrates everything from different
ways of serializing data and indexing text, to the Ruby client libraries for popular
SQL databases, to full-blown abstraction layers like ActiveRecord that save you
from having to write SQL at all.
Currently the most popular use of Ruby is in network applications (mostly through
Ruby on Rails). We devote three chapters to different types of applications:
• Chapter 15, Internet Services, kicks off our networking coverage by illustrating a
wide variety of clients and servers written with Ruby libraries.
• Chapter 16, Web Development: Ruby on Rails, covers the web application frame‐
work that’s been driving so much of Ruby’s recent popularity.
• Chapter 17, Web Development: Sinatra, covers a popular micro-web framework.
• Chapter 18, Web Services and Distributed Programming, covers two techniques
for sharing information between computers during a Ruby program. In order to
use a web service, you make an HTTP request of a program on some other com‐
puter, usually one you don’t control. Ruby’s DRb library lets you share Ruby data

xx

|

Preface

www.it-ebooks.info


structures between programs running on a set of computers, all of which you
control.

We then have three chapters on the auxilliary tasks that surround the main program‐
ming work of a project:
• Chapter 19, Testing, Debugging, Optimizing, and Documenting, focuses mainly on
handling exception conditions and creating unit tests for your code. There are
also several recipes on the processes of debugging and optimization.
• Chapter 20, Packaging and Distributing Software, mainly deals with Ruby’s Gem
packaging system and the RubyForge server that hosts many gem files. Many rec‐
ipes in other chapters require that you install a particular gem, so if you’re not
familiar with gems, we recommend you read Recipe 20.2 in particular. The chap‐
ter also shows you how to create and distribute gems for your own projects.
• Chapter 21, Automating Tasks with Rake, covers the most popular Ruby build
tool. With Rake, you can script common tasks like running unit tests or packag‐
ing your code as a gem. Though it’s usually used in Ruby projects, Rake is a
general-purpose build language that you can use wherever you might use Make.
We close the book with four chapters on miscellaneous topics:
• Chapter 22, Multitasking and Multithreading, shows how to use threads to do
more than one thing at once, and how to use Unix subprocesses to run external
commands.
• Chapter 23, User Interface, covers user interfaces (apart from the web interface,
which was covered in Chapter 16). We discuss the command-line interface,
character-based GUIs with Curses and HighLine, GUI toolkits for various plat‐
forms, and more obscure kinds of user interface (Recipe 23.11).
• Chapter 24, Extending Ruby with Other Languages, focuses on hooking up Ruby
to other languages, either for performance or to get access to more libraries. Most
of the chapter focuses on getting access to C libraries, but there is one recipe
about JRuby, the Ruby implementation that runs on the Java Virtual Machine
(Recipe 24.5).
• Chapter 25, System Administration is full of self-contained programs for doing
administrative tasks, usually using techniques from other chapters. The recipes
have a heavy focus on Unix administration, but there are some resources for

Windows users (including Recipe 25.2), and some cross-platform scripts.

Preface

www.it-ebooks.info

| xxi


How the Code Listings Work
Learning from a cookbook means performing the recipes. Some of our recipes define
big chunks of Ruby code that you can simply plop into your program and use without
really understanding them (Recipe 21.8 is a good example). But most of the recipes
demonstrate techniques, and the best way to learn a technique is to practice it.
We wrote the recipes, and their code listings, with this in mind. Most of our listings
act like unit tests for the concepts described in the recipe: they poke at objects and
show you the results.
Now, a Ruby installation comes with an interactive interpreter called irb. Within an
irb session, you can type in lines of Ruby code and see the output immediately. You
don’t have to create a Ruby program file and run it through the interpreter.

Most of our recipes are presented in a form that you can type or copy/paste directly
into an irb session. To study a recipe in depth, we recommend that you start an irb
session and run through the code listings as you read it. You’ll have a deeper under‐
standing of the concept if you do it yourself than if you just read about it. Once you’re
done, you can experiment further with the objects you defined while running the
code listings.
Sometimes we want to draw your attention to the expected result of a Ruby expres‐
sion. We do this with a Ruby comment containing an ASCII arrow that points to the
expected value of the expression. This is the same arrow irb uses to tell you the value

of every expression you type.
We also use textual comments to explain some pieces of code. Here’s a fragment of
Ruby code that we’ve formatted with comments as we would in a recipe:
1 + 2

# => 3

# On a long line, the expected value goes on a new line:
Math.sqrt(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10)
# => 7.41619848709566

To display the expected output of a Ruby expression, we use a comment that has no
ASCII arrow, and that always goes on a new line:
puts "This string is self-referential."
# This string is self-referential.

If you type these two snippets of code into irb, ignoring the comments, you can
check back against the text and verify that you got the same results we did:
$irb
irb(main):001:0> 1 + 2
=> 3
irb(main):002:0> Math.sqrt(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10)
=> 7.41619848709566

xxii

|

Preface


www.it-ebooks.info


irb(main):003:0> puts "This string is self-referential."
This string is self-referential.
=> nil

If you’re reading this book in electronic form, you can copy and paste the code frag‐
ments into irb. The Ruby interpreter will ignore the comments, but you can use them
to make sure your answers match ours, without having to look back at the text (but
you should know that typing in the code yourself, at least the first time, is better for
comprehension):
$irb
irb(main):001:0> 1 + 2 # => 3
=> 3
irb(main):002:0>
irb(main):003:0* # On a long line, the expected value goes on a new line:
irb(main):004:0* Math.sqrt(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10)
=> 7.41619848709566
irb(main):005:0> # => 7.41619848709566
irb(main):006:0*
irb(main):007:0* puts "This string is self-referential."
This string is self-referential.
=> nil
irb(main):008:0> # This string is self-referential.

We don’t cut corners. Most of our recipes demonstrate a complete irb session from
start to finish, and they include any imports or initialization necessary to illustrate the
point we’re trying to make. If you run the code exactly as it is in the recipe, you
should get the same results we did.1 This fits in with our philosophy that code sam‐

ples should be unit tests for the underlying concepts. In fact, we tested our code sam‐
ples like unit tests, with a Ruby script that parses recipe texts and runs the code list‐
ings.
The irb session technique doesn’t always work. Rails recipes have to run within Rails.
Curses recipes take over the screen and don’t play well with irb. So sometimes we
show you standalone files. We present them in the following format:
#!/usr/bin/ruby -w
# sample_ruby_file.rb: A sample file
1 + 2
Math.sqrt(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10)
puts "This string is self-referential."

Whenever possible, we’ll also show what you’ll get when you run this program; for
example, we might show a screenshot of a GUI program, or a record of the program’s
output when run from the Unix command line:
1 When a program’s behavior depends on the current time, the random number generator, or the presence of

certain files on disk, you might not get the exact same results we did, but they should be similar.

Preface

www.it-ebooks.info

|

xxiii


×