The Ruby Way, by Hal E. Fulton
pub. Sams Publishing, 2001
Table of Contents

DRAFT VERSION: May change

The Introduction is a "live link" as is the sample chapter Chapter 3 below.

Foreword by Yukihiro Matsumoto

Introduction
          How This Book Works
          What is the "Ruby Way"?

Chapter 1   Ruby in Review

          1.1 Some words on object orientation
          1.2 Basic Ruby Syntax and Semantics
          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 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.6 Expression Orientation and Other Miscellaneous Issues
          1.7 Summary

Chapter 2   Simple Data Tasks

          2.1 Strings
               2.1.1 Performing Specialized String Comparisons
               2.1.2 Tokenizing a String
               2.1.3 Formatting a String
               2.1.4 Controlling Uppercase and Lowercase
               2.1.5 Accessing and Assigning Substrings
               2.1.6 Substituting in Strings
               2.1.7 Searching a String
               2.1.8 Converting Between Characters and ASCII Codes
               2.1.9 Finding the Length of a String
               2.1.10 Processing a Line at a Time
               2.1.11 Processing a Byte at a Time
               2.1.12 Appending an Item onto a String
               2.1.13 Removing Trailing Newlines and Other Characters
               2.1.14 Trimming Whitespace from a String
               2.1.15 Repeating Strings
               2.1.16 Expanding Variables in Input
               2.1.17 Embedding Expressions Within Strings
               2.1.18 Parsing Comma-separated Data
               2.1.19 Converting Strings to Numbers (Decimal and Otherwise)
               2.1.20 Encoding and Decoding Rot13 Text
               2.1.21 Obscuring Strings
               2.1.22 Counting Characters in Strings
               2.1.23 Reversing a String
               2.1.24 Removing Duplicate Characters
               2.1.25 Removing Specific Characters from Within a String
               2.1.26 Printing Special Characters
               2.1.27 Generating Successive Strings
               2.1.28 Calculate the Levenstein Distance Between Two Strings
               2.1.29 Using Strings as Stacks and Queues
               2.1.30 Creating an Abbreviation or Acronym
               2.1.31 Encoding and Decoding Base64 Strings
               2.1.32 Encoding and Decoding Strings (uuencode/uudecode)
               2.1.33 Expanding and Compressing Tab Characters
               2.1.34 Wrapping Lines of Text
          2.2 Regular expressions
               2.2.1 Escaping Special Characters
               2.2.2 Compiling Regular Expressions
               2.2.3 Accessing Backreferences
               2.2.4 Using Character Classes
               2.2.5 Treating Newline as a Character
               2.2.6 Matching an IP Address
               2.2.7 Matching a Keyword-value Pair
               2.2.8 Matching Roman Numerals
               2.2.9 Matching Numeric Constants
          2.3 Numbers
               2.3.1 Performing Bit-level Operations on Numbers
               2.3.2 Finding Cube Roots, Fourth Roots, and so on
               2.3.3 Rounding Floating-point Values
               2.3.4 Formatting Numbers for Output
               2.3.5 Working with Very Large Integers
               2.3.6 Swapping Two Values
               2.3.7 Determining the Architecture's Byte Order
               2.3.8 Calculating the MD5 Hash of a String
               2.3.9 Calculating a 32-bit CRC
               2.3.10 Numerical Computation of a Definite Integral
               2.3.11 Trigonometry in Degrees, Radians, and Grads
               2.3.12 More Advanced Trig: arcsin, arccos, and Hyperbolic Functions
               2.3.13 Finding Logarithms with Arbitrary Bases
               2.3.14 Comparing Floating Point Numbers
               2.3.15 Finding the Mean, Median, and Mode of a Data Set
               2.3.16 Variance and Standard Deviation
               2.3.17 Finding a Correlation Coefficient
               2.3.18 Performing Base Conversions
               2.3.19 Generating Random Numbers
               2.3.20 Caching Functions for Speed
               2.3.21 Matrix Manipulation
               2.3.22 Complex Numbers
               2.3.23 Formatting Numbers with Commas
               2.3.24 Matching a Date/Time String
               2.3.25 Detecting Doubled Words in Text
               2.3.26 Matching All-caps Words
          2.4 Times and Dates
               2.4.1 Determining the Current Time
               2.4.2 Working with Specific Times (Post-epoch)
               2.4.3 Determining Day of the Week
               2.4.4 Determining the Date of Easter
               2.4.5 Finding the Nth Weekday in a Month
               2.4.6 Converting Between Seconds and Larger Units
               2.4.7 Converting to and from the Epoch
               2.4.8 Working with Leap Seconds: Don't!
               2.4.9 Finding the Day of the Year
               2.4.10 Validating a Date/Time
               2.4.11 Finding the Week of the Year
               2.4.12 Detecting Leap Years
               2.4.13 Obtaining the Time Zone
               2.4.14 Working with Hours and Minutes Only
               2.4.15 Comparing Date/Time Values
               2.4.16 Adding Intervals to Date/Time Values
               2.4.17 Computing the Difference in Two Date/Time Values
               2.4.18 Working with Specific Dates (Pre-epoch)
               2.4.19 Retrieving a Date/Time Value from a String
               2.4.20 Formatting and Printing Date/Time Values
               2.4.21 Time Zone Conversions
               2.4.22 Finding the Internet Time (@nnn)
          2.5 Summary

Chapter 3   Manipulating Structured Data

          3.1 Working with Arrays
               3.1.1 Creating and Initializing an Array
               3.1.2 Accessing and Assigning Array Elements
               3.1.3 Finding an Array's Size
               3.1.4 Comparing Arrays
               3.1.5 Sorting an Array
               3.1.6 Selecting from an Array by Criteria
               3.1.7 Using Specialized Indexing Functions
               3.1.8 Implementing a Sparse Matrix
               3.1.9 Using Arrays as Mathematical Sets
               3.1.10 Randomizing an Array
               3.1.11 Using Multidimensional Arrays
               3.1.12 Finding Elements in One Array but Not Another
               3.1.13 Transforming or Mapping Arrays
               3.1.14 Removing nil Values from an Array
               3.1.15 Removing Specific Array Elements
               3.1.16 Concatenating and Appending onto Arrays
               3.1.17 Using an Array as a Stack or Queue
               3.1.18 Iterating over an Array
               3.1.19 Interposing Delimiters to Form a String
               3.1.20 Reversing an Array
               3.1.21 Removing Duplicate Elements from an Array
               3.1.22 Interleaving Arrays
               3.1.23 Counting Frequency of Values in an Array
               3.1.24 Inverting an Array to Form a Hash
               3.1.25 Synchronized Sorting of Multiple Arrays
               3.1.26 Establishing a Default Value for New Array Elements
          3.2 Working with Hashes
               3.2.1 Creating a New Hash
               3.2.2 Specifying a Default Value for a Hash
               3.2.3 Accessing and Adding Key-value Pairs
               3.2.4 Deleting Key-value Pairs
               3.2.5 Iterating over a Hash
               3.2.6 Inverting a Hash
               3.2.7 Detecting Keys and Values in a Hash
               3.2.8 Extracting Hashes into Arrays
               3.2.9 Selecting Key-value Pairs by Criteria
               3.2.10 Sorting a Hash
               3.2.11 Merging Two Hashes
               3.2.12 Creating a Hash from an Array
               3.2.13 Finding Difference or Intersection of Hash Keys
               3.2.14 Using a Hash as a Sparse Matrix
               3.2.15 Implementing a Hash with Duplicate Keys
          3.3 Working with Stacks and Queues
               3.3.1 Implementing a Stricter Stack
               3.3.2 Converting Infix to Postfix
               3.3.3 Detecting Unbalanced Punctuation in Expressions
               3.3.4 Detecting Unbalanced Tags in HTML and XML
               3.3.5 Understanding Stacks and Recursion
               3.3.6 Implementing a Stricter Queue
               3.3.7 A Token Queue Example: Traffic Light Simulation
          3.4 Working with Trees
               3.4.1 Implementing a Binary Tree
               3.4.2 Sorting Using a Binary Tree
               3.4.3 Using a Binary Tree as a Lookup Table
               3.4.4 Converting a Tree to a String or Array
               3.4.5 Storing an Infix Expression in a Tree
               3.4.6 Additional Notes on Trees
          3.5 Working with Graphs
               3.5.1 Implementing a Graph as an Adjacency Matrix
               3.5.2 Determining Whether a Graph is Fully Connected
               3.5.3 Determining Whether a Graph has an Euler Circuit
               3.5.4 Determining Whether a Graph has an Euler Path
               3.5.5 Hints for More Complex Graphs
          3.6 Summary

Chapter 4   External Data Manipulation

          4.1 4.1 Working with Files and Directories
               4.1.1 Opening and Closing Files
               4.1.2 Updating a File
               4.1.3 Appending to a File
               4.1.4 Random Access to Files
               4.1.5 Working with Binary Files
               4.1.6 Locking Files
               4.1.7 Performing Simple I/O
               4.1.8 Performing Buffered and Unbuffered I/O
               4.1.9 Manipulating File Ownership and Permissions
               4.1.10 Retrieving and Setting Timestamp Information
               4.1.11 Checking File Existence and Size
               4.1.12 Checking Special File Characteristics
               4.1.13 Working with Pipes
               4.1.14 Performing Special I/O Operations
               4.1.15 Manipulating Pathnames
               4.1.16 Command-level File Manipulation
               4.1.17 Grabbing Characters from the Keyboard
               4.1.18 Reading an Entire File into Memory
               4.1.19 Iterating Over a File by Lines
               4.1.20 Iterating Over a File by Byte
               4.1.21 Treating a String as a File
               4.1.22 Reading Data Embedded in a Program
               4.1.23 Reading Program Source
               4.1.24 Performing Newline Conversion
               4.1.25 Working with Temporary Files
               4.1.26 Changing and Setting the Current Directory
               4.1.27 Changing the Current Root
               4.1.28 Iterating over Directory Entries
               4.1.29 Getting a List of Directory Entries
               4.1.30 Creating a Chain of Directories
               4.1.31 Deleting a Directory Recursively
               4.1.32 Finding Files and Directories
          4.2 Performing Higher-level Data Access
               4.2.1 Simple Marshaling
               4.2.2 More Complex Marshaling
               4.2.3 Performing Limited "Deep Copying" Using Marshal
               4.2.4 Better Object Persistence with PStore
               4.2.5 Using the DBM library
          4.3 Connecting to external databases
               4.3.1 Interfacing to MySQL
               4.3.2 Interfacing to PostgreSQL
               4.3.3 Working with CSV Data
               4.3.4 Interfacing to Other Databases: See the RAA
          4.4 Summary

Chapter 5   OOP and Dynamicity in Ruby

          5.1 Everyday OOP Tasks
               5.1.1 Using Multiple Constructors
               5.1.2 Creating Instance Attributes
               5.1.3 More Elaborate Constructors
               5.1.4 Creating Class-level Attributes and Methods
               5.1.5 Inheriting from a Superclass
               5.1.6 Testing Types or Classes of Objects
               5.1.7 Testing Equality of Objects
               5.1.8 Controlling Access to Methods
               5.1.9 Copying an Object
               5.1.10 Working with Modules
               5.1.11 Transforming or Converting Objects
               5.1.12 Creating Data-only Classes (Structs)
               5.1.13 Freezing Objects
          5.2 More Advanced Techniques
               5.2.1 Sending an Explicit Message to an Object
               5.2.2 Specializing an Individual Object
               5.2.3 Nesting Classes and Modules
               5.2.4 Creating Parametric Classes
               5.2.5 Using Continuations to Implement a Generator
               5.2.6 Storing Code as Objects
               5.2.7 Automatically Defining Class-level Readers and Writers
               5.2.8 Working in Advanced Programming Discplines
          5.3 Working with Dynamic Features
               5.3.1 Evaluating Code Dynamically
               5.3.2 Removing Definitions
               5.3.3 Obtaining Lists of Defined Entities
               5.3.4 Examining the call stack
               5.3.5 Monitoring Execution of a Program
               5.3.6 Traversing the Object Space
               5.3.7 Handling Calls to Nonexistent Methods
               5.3.8 Tracking Changes to a Class or Object Definition
               5.3.9 Defining Finalizers for Objects
               5.3.10 Dynamically Instantiating a Class by Name
          5.4 Summary

Chapter 6   Graphical Interfaces in Ruby

          6.1 Ruby/Tk
               6.1.1 Overview
               6.1.2 A Trivial Windowed Application
               6.1.3 Working with Buttons
               6.1.4 Working with Text Fields
               6.1.5 Working with Other Widgets
               6.1.6 Other Notes
          6.2 Ruby/GTK
               6.2.1 Overview
               6.2.2 A Trivial Windowed Application
               6.2.3 Working with Buttons
               6.2.4 Working with Text Fields
               6.2.5 Working with Other Widgets
               6.2.6 Other Notes
          6.3 FX/Ruby (FOX)
               6.3.1 Overview
               6.3.2 A Trivial Windowed Application
               6.3.3 Working with Buttons
               6.3.4 Working with Text Fields
               6.3.5 Working with Other Widgets
               6.3.6 Other Notes
          6.4 Others
               6.4.1 The (Non-graphical) curses Environment
               6.4.2 Ruby and X
               6.4.3 Ruby and Qt
               6.4.4 Ruby and wxWindows (not yet)
               6.4.5 Apollo (Ruby and Delphi)
               6.4.6 Ruby and the Windows API
          6.5 Summary

Chapter 7   Threads in Ruby

          7.1 Creating and Manipulating Threads
               7.1.1 Creating Threads
               7.1.2 Accessing Thread-local Variables
               7.1.3 Querying and Changing Thread Status
               7.1.4 Achieving a Rendezvous (and Capturing a Return Value)
               7.1.5 Dealing with Exceptions
               7.1.6 Using a Thread Group
          7.2 Synchronizing threads
               7.2.1 Performing Simple Synchronization with Critical Sections
               7.2.2 Synchronizing Access to Resources (mutex.rb)
               7.2.3 Using the Predefined Synchronized Queue Classes
               7.2.4 Using Condition Variables
               7.2.5 Using Other Synchronization Techniques (monitor.rb, sync.rb)
               7.2.6 Allowing Timeout of an Operation
               7.2.7 Waiting for an Event
               7.2.8 Continuing Processing During I/O
               7.2.9 Implementing Parallel Iterators
               7.2.10 Recursive Deletion in Parallel
          7.3 Summary

Chapter 8   Scripting and System Administration

          8.1 Running External Programs
               8.1.1 Using system and exec
               8.1.2 Command Output Substitution
               8.1.3 Manipulating Processes
               8.1.4 Manipulating Standard Input/Output
          8.2 Command-line Options and Arguments
               8.2.1 Parsing Command-line Options
               8.2.2 Working with ARGF
               8.2.3 Working with ARGV
          8.3 The Shell Library
               8.3.1 Using Shell for I/O Redirection
               8.3.2 Other Notes on shell.rb
          8.4 Accessing Environment Variables
               8.4.1 Getting and Setting Environment Variables
               8.4.2 Storing Environment Variables as an Array or Hash
               8.4.3 Importing Environment Variables as Globals
          8.5 Scripting in Microsoft Windows
               8.5.1 Using Win32API
               8.5.2 Using Win32OLE
               8.5.3 Using ActiveScriptRuby
          8.6 Working with Files, Directories, and Trees
               8.6.1 A Few Words on Text Filters
               8.6.2 Copying a Directory Tree (with symlinks)
               8.6.3 Deleting Files by Age or Other Criteria
               8.6.4 Determining Free Space on a Disk
          8.7 Miscellaneous Scripting Tasks
               8.7.1 Piping into the Ruby Interpreter
               8.7.2 Getting and Setting Exit Codes
               8.7.3 Testing Whether a Program Is Running Interactively
               8.7.4 Determining the Current Platform or Operating System
               8.7.5 Using the Etc Module
               8.7.6 Libraries and Utilities You Should Know About
          8.8 Summary

Chapter 9   Network and Web Programming

          9.1 Network Servers
               9.1.1 A Simple Serialized Server: Time of Day
               9.1.2 Implementing a Threaded Server
               9.1.3 Case Study: A Peer-to-Peer Chess Server
          9.2 Network Clients
               9.2.1 Retrieving Truly Random Numbers from the Web
               9.2.2 Contacting an Official Timeserver
               9.2.3 Interacting with a POP Server
               9.2.4 Sending Mail with SMTP
               9.2.5 Retrieving a Web Page from a Specified URL
               9.2.6 Case study: A Mail-news Gateway
          9.3 Ruby and the Web Server
               9.3.1 Self-contained Web Servers
               9.3.2 Using Embedded Ruby
               9.3.3 Using mod_ruby
          9.4 Ruby and CGI Programming
               9.4.1 Overview: Using the CGI Library
               9.4.2 Displaying and Processing Forms
               9.4.3 Working with Cookies
               9.4.4 Working with User Sessions
               9.4.5 Using FastCGI
               9.4.6 Case Study: A Message Board
          9.5 Distributed Ruby
               9.5.1 An Overview: Using drb
               9.5.2 Case Study: A Stock Ticker Simulation
          9.6 XML Parsing in Ruby
               9.6.1 Using XMLParser (DOM-like processing)
               9.6.2 Using XMLParser (SAX-like processing)
               9.6.3 Using NQXML
          9.7 Summary
Appendix A From Perl to Ruby
Appendix B From Python to Ruby
Appendix C Programming Tools and Utilities
Appendix D Web and Print Resources
Appendix E Changes in Ruby 1.8