The Ruby Way, 2nd ed.
Introduction
Preface to 2nd Edition
Using this Book
What is the "Ruby Way"?
Notes on 2nd Edition
Chapter 1: Ruby in Review
  1.1 Some Words on Object Orientation
  1.2 Basic Ruby Syntax and Semantics
    1.2.1 Keywords and Identifiers
    1.2.2 Comments and Embedded Documentation
    1.2.3 Constants, Variables, and Types
    1.2.4 Operators and Precedence
    1.2.5 A Sample Program
    1.2.6 Looping and Branching
    1.2.7 Exceptions
  1.3 OOP in Ruby
    1.3.1 Objects
    1.3.2 Built-in Classes
    1.3.3 Modules and Mixins
    1.3.4 Creating Classes
    1.3.5 Methods and Attributes
  1.4 Dynamic Aspects of Ruby
    1.4.1 Coding at Runtime
    1.4.2 Reflection
    1.4.3 Missing Methods
    1.4.4 Garbage Collection
  1.5 Training Your Intuition: Things to Remember
    1.5.1 Syntax Issues
    1.5.2 Perspectives in Programming
    1.5.3 Ruby's Case Statement
    1.5.4 Rubyisms and Idioms
    1.5.5 Expression Orientation and Other Miscellaneo...
  1.6 Jargon and slang
  1.7 Conclusion
Chapter 2: Manipulating Strings
  2.1 Representing Ordinary Strings
  2.2 Representing Strings with Alternate Notations
  2.3 Using Here-Documents 
  2.4 Finding the Length of a String
  2.5 Processing a Line at a Time
  2.6 Processing a Byte at a Time
  2.7 Performing Specialized String Comparisons
  2.8 Tokenizing a String
  2.9 Formatting a String
  2.10 Using Strings as IO Objects (StringIO)
  2.11 Controlling Uppercase and Lowercase
  2.12 Accessing and Assigning Substrings
  2.13 Substituting in Strings
  2.14 Searching a String
  2.15 Converting Between Characters and ASCII Codes
  2.16 Implicit and Explicit Conversion (to_s, to_str)
  2.17 Appending an Item onto a String
  2.18 Removing Trailing Newlines and Other Characters
  2.19 Trimming Whitespace from a String
  2.20 Repeating Strings
  2.21 Embedding Expressions Within Strings
  2.22 Delayed Interpolation of Strings
  2.23 Parsing Comma-Separated Data
  2.24 Converting Strings to Numbers (Decimal and Otherwise)
  2.25 Encoding and Decoding rot13 Text
  2.26 Encrypting a String
  2.27 Compressing a String
  2.28 Counting Characters in Strings
  2.29 Reversing a String
  2.30 Removing Duplicate Characters
  2.31 Removing Specific Characters
  2.32 Printing Special Characters
  2.33 Generating Successive Strings
  2.34 Calculating a 32-bit CRC
  2.35 Calculating the MD5 Hash of a String
  2.36 Calculate the Levenshtein Distance Between Two Strings
  2.37 Encoding and decoding base64 Strings
  2.38 Encoding and Decoding Strings (uuencode/uud...
  2.39 Expanding and Compressing Tab Characters
  2.40 Wrapping Lines of Text
  2.41 Conclusion
Chapter 3: Manipulating Regular Expressions
  3.1 Regular Expression Syntax
  3.2 Compiling Regular Expressions
  3.3 Escaping Special Characters
  3.4 Using Anchors
  3.5 Using Quantifiers
  3.6 Positive and Negative Lookahead
  3.7 Accessing Backreferences
  3.8 Using Character Classes
  3.9 Extended Regular Expressions
  3.10 Matching a Newline with a Dot
  3.11 Using Embedded Options
  3.12 Using Embedded Sub-expressions
  3.13 Ruby and Oniguruma
    3.13.1 Testing the Presence of Oniguruma
    3.13.2 Building Oniguruma
    3.13.3 A Few New Features of Oniguruma
    3.13.4 Positive and Negative Lookbehind
    3.13.5 More on Quantifiers
    3.13.6 Named Matches
    3.13.7 Recursion in Regular Expressions
  3.14 A Few Sample Regular Expressions
    3.14.1 Matching an IP address
    3.14.2 Matching a Keyword-Value Pair
    3.14.3 Matching Roman Numerals
    3.14.4 Matching Numeric Constants
    3.14.5 Matching a Date-time String
    3.14.6 Detecting Doubled Words in Text
    3.14.7 Matching All-caps Words
    3.14.8 Matching Version Numbers
    3.14.9 A Few Other Patterns
  3.15 Conclusion
Chapter 4: Internationalization in Ruby
  4.1 Overview
  4.2 Coding in a Post-ASCII World
    4.2.1 The jcode Library and $KCODE
    4.2.2 Revisiting Common String and Regex Operations
    4.2.3 Detecting Character Encodings
    4.2.4 Normalizing Unicode Strings
    4.2.5 Issues in String Collation
    4.2.6 Converting Between Encodings
  4.3 Using Message Catalogs
    4.3.1 Overview
    4.3.2 Getting Started with Message Catalogs
    4.3.3 A Simple Example
    4.3.4 Other Notes
  4.4 Conclusion
Chapter 5: Performing Numerical Calculations
  5.1 Representing Numbers in Ruby
  5.2 Basic Operations on Numbers
  5.3 Rounding Floating Point Values
  5.4 Comparing Floating Point Numbers
  5.5 Formatting Numbers for Output
  5.6 Formatting Numbers with Commas
  5.7 Working with Very Large Numbers
  5.8 Using BigDecimal
  5.9 Working with Rational Values
  5.10 Matrix Manipulation
  5.11 Working with Complex Numbers
  5.12 Using mathn
  5.13 Finding Prime Factorization, GCD, and LCM
  5.14 Working with Prime Numbers
  5.15 Implicit and Explicit Numeric Conversion
  5.16 Coercing Numeric Values
  5.17 Performing Bit-level Operations on Numbers
  5.18 Performing Base Conversions
  5.19 Finding Cube Roots, Fourth Roots, etc.
  5.20 Determining the Architecture's Byte Order
  5.21 Numerical Computation of a Definite Integral
  5.22 Trigonometry in Degrees, Radians, and Grads
  5.23 More Advanced Trigonometry
  5.24 Finding Logarithms with Arbitrary Bases
  5.25 Finding the Mean, Median, and Mode of a Data Set
  5.26 Finding Variance and Standard Deviation
  5.27 Finding a Correlation Coefficient
  5.28 Generating Random Numbers
  5.29 Caching Functions with memoize
  5.30 Conclusion
Chapter 6: Using Symbols and Ranges
  6.1 Symbols
    6.1.1  Symbols as Enumerations
    6.1.2  Symbols as Meta-values
    6.1.3  Symbols, Variables, and Methods
    6.1.4  Converting To/from Symbols
  6.2 Ranges 
    6.2.1  Open and Closed Ranges
    6.2.2  Finding Endpoints
    6.2.3  Iterating over Ranges
    6.2.4  Testing Range Membership
    6.2.5  Converting to Arrays
    6.2.6  Backward Ranges
    6.2.7  The Flip-flop Operator
    6.2.8  Custom Ranges
  6.3 Conclusion
Chapter 7: Manipulating Times and Dates
  7.1 Determining the Current Time
  7.2 Working with Specific Times (Post-epoch)
  7.3 Determining Day of the Week
  7.4 Determining the Date of Easter
  7.5 Finding the Nth Weekday in a Month
  7.6 Converting Between Seconds and Larger Units
  7.7 Converting to and from the Epoch
  7.8 Working with Leap Seconds: Don't!
  7.9 Finding the Day of the Year
  7.10 Validating a Date/Time
  7.11 Finding the Week of the Year
  7.12 Detecting Leap Years
  7.13 Obtaining the Time Zone
  7.14 Working with Hours and Minutes Only
  7.15 Comparing Date/Time Values
  7.16 Adding Intervals to Date/Time Values
  7.17 Computing the Difference in two date/time Values
  7.18 Working with Specific Dates (Pre-epoch)
  7.19 Interconverting Between Time, Date, and DateTime
  7.20 Retrieving a Date/Time Value from a String
  7.21 Formatting and Printing Date/Time Values
  7.22 Time Zone Conversions
  7.23 Determining the Number of Days in a Month
  7.24 Dividing a Month into Weeks
  7.25 Date and Time vs. DateTime
  7.26 Conclusion
Chapter 8: Arrays, Hashes, and Other Enumerables
  8.1 Working with Arrays
    8.1.1 Creating and Initializing an Array
    8.1.2 Accessing and Assigning Elements
    8.1.3 Finding an Array's Size
    8.1.4 Comparing Arrays
    8.1.5 Sorting an Array
    8.1.6 Selecting from an Array by Criteria
    8.1.7 Using Specialized Indexing Functions
    8.1.8 Implementing a Sparse Matrix
    8.1.9 Using Arrays as Mathematical Sets
    8.1.10 Randomizing an Array
    8.1.11 Using Multidimensional Arrays
    8.1.12 Finding Elements in One Array but Not Another
    8.1.13 Transforming or Mapping Arrays
    8.1.14 Removing nil Values from an Array
    8.1.15 Removing Specific Array Elements
    8.1.16 Concatenating and Appending
    8.1.17 Iterating Over an Array
    8.1.18 Interposing Delimiters to Form a String
    8.1.19 Reversing an Array
    8.1.20 Removing Duplicate Elements
    8.1.21 Interleaving Arrays
    8.1.22 Counting Frequency of Values in an Array
    8.1.23 Inverting an Array to Form a Hash
    8.1.24 Synchronized Sorting of Multiple Arrays
    8.1.25 Establishing a Default Value for New Array Elements
  8.2 Working with Hashes
    8.2.1 Creating a New Hash
    8.2.2 Specifying a Default Value
    8.2.3 Accessing and Adding Key-Value Pairs
    8.2.4 Deleting Key-Value Pairs
    8.2.5 Iterating Over a Hash
    8.2.6 Inverting a Hash
    8.2.7 Detecting Keys and Values
    8.2.8 Extracting Hashes into Arrays
    8.2.9 Selecting Key-Value Pairs by Criteria
    8.2.10 Sorting a Hash
    8.2.11 Merging Two Hashes
    8.2.12 Creating a Hash from an Array
    8.2.13 Finding Differences or Intersections of Hash Keys
    8.2.14 Using a Hash as a Sparse Matrix
    8.2.15 Implementing a Hash with Duplicate Keys
  8.3 Enumerable Collections in General
    8.3.1 The inject Method
    8.3.2 Using Quantifiers
    8.3.3 The partitition Method
    8.3.4 Iterating by Groups
    8.3.5 Converting to Arrays or Sets
    8.3.6 Using Enumerator Objects
    8.3.7 Using Generator Objects
  8.4 Conclusion
Chapter 9: More Advanced Data Structures
  9.1 Working with Sets
    9.1.1 Simple Set Operations
    9.1.2 More Advanced Set Operations
  9.2 Working with Stacks and Queues
    9.2.1 Implementing a Stricter Stack
    9.2.2 Detecting Unbalanced Punctuation
    9.2.3 Understanding Stacks and Recursion
    9.2.4 Implementing a Stricter Queue
  9.3 Working with Trees
    9.3.1 Implementing a Binary Tree
    9.3.2 Sorting Using a Binary Tree
    9.3.3 A Binary Tree as a Lookup Table
    9.3.4 Converting a Tree to a String or Array
  9.4 Working with Graphs
    9.4.1 Implementing a Graph as an Adjacency Matrix
    9.4.2 Determining Whether a Graph is Fully Connected
    9.4.3 Determining Whether a Graph has an Euler Circuit
    9.4.4 Determining Whether a Graph has an Euler Path
    9.4.5 Graph Tools in Ruby
  9.5 Conclusion
Chapter 10: Manipulating files and external data
  10.1 I/O and Data Storage
    10.1.1 Opening and Closing Files
    10.1.2 Updating a File
    10.1.3 Appending to a File
    10.1.4 Random Access to Files
    10.1.5 Working with Binary Files
    10.1.6 Locking Files
    10.1.7 Performing Simple I/O
    10.1.8 Performing Buffered and Unbuffered I/O
    10.1.9 Manipulating File Ownership and Permissions
    10.1.10 Retrieving and Setting Timestamp Information
    10.1.11 Checking File Existence and Size
    10.1.12 Checking Special File Characteristics
    10.1.13 Working with Pipes
    10.1.14 Performing Special I/O Operations
    10.1.15 Non-blocking I/O and Threads
    10.1.16 Using readpartial
    10.1.17 Manipulating Pathnames
    10.1.18 Using the Pathname Class
    10.1.19 Command-level File Manipulation
    10.1.20 Grabbing Characters From the Keyboard
    10.1.21 Reading an Entire File into Memory
    10.1.22 Iterating Over a File by Lines
    10.1.23 Iterating Over a File by Byte
    10.1.24 Using Strings as IO Objects
    10.1.25 Reading Data Embedded in a Program
    10.1.26 Reading Program Source
    10.1.27 Working with Temporary Files
    10.1.28 Changing and Setting the Current Directory
    10.1.29 Changing the Current Root
    10.1.30 Iterating Over Directory Entries
    10.1.31 Getting a List of Directory Entries
    10.1.32 Creating a Chain of Directories
    10.1.33 Deleting a Directory Recursively
    10.1.34 Finding Files and Directories
  10.2 Performing Higher-Level Data Access
    10.2.1 Simple Marshaling
    10.2.2 More Complex Marshaling
    10.2.3 Performing Limited "Deep Copying" Using Marshal
    10.2.4 Better Object Persistence with PStore
    10.2.5 Working with CSV Data
    10.2.6 Marshaling with YAML
    10.2.7 Using Madeleine
    10.2.8 Using the DBM Library
    10.2.9 Using KirbyBase 
  10.3 Connecting to External Databases
    10.3.1 Interfacing to SQLite
    10.3.2 Interfacing to MySQL
    10.3.3 Interfacing to PostgreSQL
    10.3.4 Interfacing to LDAP
    10.3.5 Interfacing to Oracle 
    10.3.6 Using the DBI Wrapper
    10.3.7 Object-Relational Mappers (ORMs)
  10.4 Conclusion
Chapter 11: Ruby and OOP
  11.1 Everyday OOP Tasks
    11.1.1 Using Multiple Constructors
    11.1.2 Creating Instance Attributes
    11.1.3 More Elaborate Constructors
    11.1.4 Creating Class-Level Attributes and Methods
    11.1.5 Inheriting from a Superclass
    11.1.6 Testing Classes of Objects
    11.1.7 Testing Equality of Objects
    11.1.8 Controlling Access to Methods
    11.1.9 Copying an Object
    11.1.10 Using initialize_copy
    11.1.11 Understanding allocate
    11.1.12 Working with Modules
    11.1.13 Transforming or Converting Objects
    11.1.14 Creating Data-Only Classes (Structs)
    11.1.15 Freezing Objects
  11.2 More Advanced Techniques
    11.2.1 Sending an Explicit Message to an Object
    11.2.2 Specializing an Individual Object
    11.2.3 Nesting Classes and Modules
    11.2.4 Creating Parametric Classes
    11.2.5 Storing Code as Objects
    11.2.6 How Module Inclusion Works
    11.2.7 Detecting Default Parameters
    11.2.8 Forwarding and Delegating
    11.2.9 Class-Level Readers and Writers
    11.2.10 Working in Advanced Programming Disciplines
  11.3 Working with Other Dynamic Features
    11.3.1 Evaluating Code Dynamically
    11.3.2 Using const_get
    11.3.3 Dynamically Instantiating a Class by Name
    11.3.4 Getting and Setting Instance Variables
    11.3.5 Using define_method 
    11.3.6 Using const_missing
    11.3.7 Removing Definitions
    11.3.8 Obtaining Lists of Defined Entities
    11.3.9 Examining the Call Stack
    11.3.10 Monitoring Execution of a Program
    11.3.11 Traversing the Object Space
    11.3.12 Tracking Changes to a Class or Object Defini...
    11.3.13 Defining Finalizers for Objects
  11.4 Conclusion
Chapter 12: Graphical Interfaces for Ruby
  12.1 Ruby/Tk
    12.1.1 Overview
    12.1.2 A Simple Windowed Application
    12.1.3 Working with Buttons
    12.1.4 Working with Text Fields
    12.1.5 Working with Other Widgets
    12.1.6 Other Notes
  12.2 Ruby/GTK
    12.2.1 Overview
    12.2.2 A Simple Windowed Application
    12.2.3 Working with Buttons
    12.2.4 Working with Text Fields
    12.2.5 Working with Other Widgets
    12.2.6 Other Notes
  12.3 FXRuby (FOX)
    12.3.1 Overview
    12.3.2 A Simple Windowed Application
    12.3.3 Working with Buttons
    12.3.4 Working with Text Fields
    12.3.5 Working with Other Widgets
    12.3.6 Other Notes
  12.4 QtRuby
    12.4.1 Overview
    12.4.2 A Simple Windowed Application
    12.4.3 Working with Buttons
    12.4.4 Working with Text Fields
    12.4.5 Working with Other Widgets
    12.4.6 Other Notes
  12.5 Others
    12.5.1 Ruby and X
    12.5.2 Ruby and wxWindows
    12.5.3 Apollo? (Ruby and Delphi)
    12.5.4 Ruby and the Windows API
  12.6 Conclusion
Chapter 13: Threads in Ruby 
  13.1 Creating and Manipulating Threads
    13.1.1 Creating Threads
    13.1.2 Accessing Thread-Local Variables
    13.1.3 Querying and Changing Thread Status
    13.1.4 Achieving a Rendezvous (and Capturing a Retu...
    13.1.5 Dealing with Exceptions
    13.1.6 Using a Thread Group
  13.2 Synchronizing Threads
    13.2.1 Performing Simple Synchronization with Criti...
    13.2.2 Synchronizing Access to Resources (mutex.rb)
    13.2.3 Using the Predefined Synchronized Queue Classes
    13.2.4 Using Condition Variables
    13.2.5 Using Other Synchronization Techniques (moni...
    13.2.6 Allowing Timeout of an Operation
    13.2.7 Waiting for an Event
    13.2.8 Continuing Processing during I/O
    13.2.9 Implementing Parallel Iterators
    13.2.10 Recursive Deletion in Parallel
  13.3 Conclusion
Chapter 14: System Administration and Scripting
  14.1 Running External Programs
    14.1.1 Using system and exec
    14.1.2 Command Output Substitution
    14.1.3 Manipulating Processes
    14.1.4 Manipulating Standard Input/Output
  14.2 Command-line Options and Arguments
    14.2.1 Parsing Command Line Options
    14.2.2 Working with ARGF
    14.2.3 Working with ARGV
  14.3 The Shell library
    14.3.1 Using Shell for I/O Redirection
    14.3.2 Other Notes on shell.rb
  14.4 Accessing Environment Variables
  14.5 Windows
    14.5.1 Using Win32API
    14.5.2 Using Win32OLE
    14.5.3 Using ActiveScriptRuby
    14.5.4 The Windows One-click Installer
    14.5.5 Single-file Executables
    14.5.6 Libaries You Should Know About
  14.6 Working with Files, Directories, and Trees
    14.6.1 A Few Words on Text Filters
    14.6.2 Copying a Directory Tree (With Symlinks)
    14.6.3 Deleting Files by Age or Other Criteria
    14.6.4 Determining Free Space on a Disk
  14.7 Other
    14.7.1 Piping into the Ruby Interpreter
    14.7.2 Getting and Setting Exit Codes
    14.7.3 Testing Whether a Program is Running Interac...
    14.7.4 Determining the Current Platform or Operatin...
    14.7.5 Using the Etc Module
    14.7.6 Libraries and Utilities You Should Know About
  14.8 Conclusion
Chapter 15: Ruby and Data Formats
  15.1 Parsing XML with REXML
  15.2 Using YAML
  15.3 Working with RSS and Atom
  15.4 Manipulating Image Data (RMagick)
  15.5 Ruby and Flash
  15.6 Writing PDF files
  15.7 Manipulating Color Data in Documents and Images
  15.8 Conclusion
Chapter 16: Testing and Debugging
  16.1 Using irb 
  16.2 Testing with Test::Unit
  16.3 Using xmp
  16.4 Prettyprinting Objects
  16.5 Measuring Code Coverage
  16.6 Using $-v and Other Globals
  16.7 Performance Issues
  16.8 Conclusion
Chapter 17: Packaging and Distributing Code
  17.1 RDoc and Documentation in General
  17.2 Installation and Packaging
  17.3 RubyGems
  17.4 Distribution Options
  17.5 RubyForge and the RAA
  17.6 Conclusion
Chapter 18: Network Programming
  18.1 Network Servers
    18.1.1 A Simple Server: Time of Day
    18.1.2 Implementing a Threaded Server
    18.1.3 Case Study: A Peer-to-peer Chess Server
  18.2 Network Clients
    18.2.1 Retrieving Truly Random Numbers from the Web
    18.2.2 Contacting an Official Timeserver
    18.2.3 Interacting with a POP Server
    18.2.4 Encoding/Decoding Email Attachments
    18.2.5 Interacting with an IMAP Server 
    18.2.6 Case study: A Mail-News Gateway
    18.2.7 Retrieving a Document from a Specified URL
    18.2.8 Using OpenURI
  18.3 Conclusion
Chapter 19: Ruby and Web Applications
  19.1 Overview: Using the cgi Library
    19.2 Working with Cookies
    19.3 Working with User Sessions
    19.4 Displaying and Processing Forms
    19.5 Using fastcgi.rb
  19.6 Ruby on Rails
    19.6.1 Introduction
    19.6.2 Principles and Techniques
    19.6.3 Two ways of Scaffolding
    19.6.4 Debugging Rails Apps
    19.6.5 Apps without Databases
    19.6.6 Core Extensions
    19.6.7 Related Tools and Libs
  19.7 Nitro
    19.8 Introduction
    19.9 Principles and Techniques
  19.10 Other Web Frameworks
  19.11 Ruby and the Web Server
    19.11.1 Using WEBrick
    19.11.2 Using mod_ruby
    19.11.3 Using eruby
  19.12 Ruby and Web Services
    19.12.1 SOAP
    19.12.2 REST
  19.13 Conclusion
Chapter 20: Distributed Ruby
  20.1 An overview: Using dRuby
        20.1.1 Case Study: A Stock Ticker Simulation
        20.1.2 More on dRuby
  20.2 XML-RPC 
  20.3 Okay (YAML)
  20.4 Rinda and Ring
  20.5 Conclusion
Chapter 21: Ruby and External Software
  21.1 Understanding Rake
  21.2 Understanding mkmf and extconf.rb 
  21.3 Embedding a Ruby Interpreter into a C/C++ Program 
  21.4 Making Ruby a DLL-able Plugin for Another Program 
  21.5 Using SWIG with Ruby 
  21.6 Ruby/DL
  21.7 Interfacing with gnuplot
  21.8 Ruby and Mozilla
  21.9 Ruby and Java
  21.10 Ruby and .NET
  21.11 Conclusion
Chapter 22: Ruby Development Tools
  22.1 RubyGems 
    22.1.1 Basic Usage
    22.1.2 Running a Gem Server
    22.1.3 Writing a Gem Spec
  22.2 RDoc
    22.2.1 Overview
    22.2.2 Customizing
    22.2.3 Templating
  22.3 The ri Utility
  22.4 Editor Support 
    22.4.1 vim
    22.4.2 emacs
    22.4.3 Others
  22.5 Integrated Development Environments
    22.5.1 FreeRIDE
    22.5.2 RDE
    22.5.3 ArachnoRuby
    22.5.4 Eclipse
    22.5.5 Komodo
  22.6 Conclusion
Chapter 23: The Ruby Community
  23.1 Web Resources
  23.2 Newsgroup and Mailing Lists
  23.3 Blogs and Online Magazines
  23.4 Ruby Change Requests (RCRs)
  23.5 IRC Channels
  23.6 Ruby Conferences
  23.7 Local Ruby Groups
  23.8 Conclusion