SECOND EDITION Ruby Cookbook, 2E Lucas Carlson and Leonard Richardson Ruby Cookbook, 2E, Second Edition by Lucas Carlson and Leonard Richardson Copyright © 2010 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 (http://my.safaribooksonline.com). For more information, contact our corporate/ institutional sales department: 800-998-9938 or [email protected]. Editors: Brian Anderson and Allyson MacDonald Indexer: FIX ME! Production Editor: FIX ME! Cover Designer: Karen Montgomery Copyeditor: FIX ME! Interior Designer: David Futato Proofreader: FIX ME! Illustrator: Rebecca Demarest November 2014: Second Edition Revision History for the Second Edition: 2014-04-30: First Early Release revision 1 See http://oreilly.com/catalog/errata.csp?isbn=9781449373719 for release details. Nutshell Handbook, the Nutshell Handbook logo, and the O’Reilly logo are registered trademarks of O’Reilly Media, Inc. !!FILL THIS IN!! and related trade dress are trademarks of O’Reilly Media, Inc. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this book, and O’Reilly Media, Inc. was aware of a trademark claim, the designations have been printed in caps or initial caps. While every precaution has been taken in the preparation of this book, the publisher and authors assume no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein. ISBN: 978-1-449-37371-9 [?] 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 Table of Contents Preface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii 1. Ruby 2.1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1. What’s Different Between Ruby 1.8 and 2.1? 2 1.2. YARV (Yet Another Ruby VM) Bytecode Interpreter 7 1.3. Syntax Changes 9 1.4. Keyword Arguments 11 1.5. Performance Enhancements 12 1.6. Refinements 14 1.7. Debugging with DTrace and TracePoint 15 1.8. Module Prepending 17 1.9. New Methods 18 1.10. New Classes 21 1.11. New Standard Libraries 23 1.12. What’s Next? 25 2. Strings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2.1. Building a String from Parts 31 2.2. Substituting Variables into Strings 32 2.3. Substituting Variables into an Existing String 35 2.4. Reversing a String by Words or Characters 37 2.5. Representing Unprintable Characters 38 2.6. Converting Between Characters and Values 41 2.7. Converting Between Strings and Symbols 42 2.8. Processing a String One Character at a Time 43 2.9. Processing a String One Word at a Time 45 2.10. Changing the Case of a String 46 2.11. Managing Whitespace 48 2.12. Testing Whether an Object Is String-Like 50 v 2.13. Getting the Parts of a String You Want 51 2.14. Word-Wrapping Lines of Text 52 2.15. Generating a Succession of Strings 54 2.16. Matching Strings with Regular Expressions 57 2.17. Replacing Multiple Patterns in a Single Pass 59 2.18. Validating an Email Address 61 2.19. Classifying Text with a Bayesian Analyzer 64 3. Numbers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 3.1. Parsing a Number from a String 68 3.2. Comparing Floating-Point Numbers 71 3.3. Representing Numbers to Arbitrary Precision 74 3.4. Representing Rational Numbers 77 3.5. Generating Random Numbers 79 3.6. Converting Between Numeric Bases 80 3.7. Taking Logarithms 82 3.8. Finding Mean, Median, and Mode 84 3.9. Converting Between Degrees and Radians 87 3.10. Multiplying Matrices 88 3.11. Solving a System of Linear Equations 93 3.12. Using Complex Numbers 95 3.13. Simulating a Subclass of Fixnum 98 3.14. Doing Math with Roman Numbers 102 3.15. Generating a Sequence of Numbers 107 3.16. Generating Prime Numbers 110 3.17. Checking a Credit Card Checksum 115 4. Date and Time. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 4.1. Finding Today’s Date 120 4.2. Parsing Dates, Precisely or Fuzzily 124 4.3. Printing a Date 127 4.4. Iterating Over Dates 131 4.5. Doing Date Arithmetic 133 4.6. Counting the Days Since an Arbitrary Date 135 4.7. Converting Between Time Zones 137 4.8. Checking Whether Daylight Saving Time Is in Effect 139 4.9. Converting Between Time and DateTime Objects 141 4.10. Finding the Day of the Week 144 4.11. Handling Commercial Dates 146 4.12. Running a Code Block Periodically 147 4.13. Waiting a Certain Amount of Time 149 vi | Table of Contents 4.14. Adding a Timeout to a Long-Running Operation 152 5. Arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 5.1. Iterating Over an Array 157 5.2. Rearranging Values Without Using Temporary Variables 161 5.3. Stripping Duplicate Elements from an Array 163 5.4. Reversing an Array 164 5.5. Sorting an Array 165 5.6. Ignoring Case When Sorting Strings 167 5.7. Making Sure a Sorted Array Stays Sorted 168 5.8. Summing the Items of an Array 174 5.9. Sorting an Array by Frequency of Appearance 175 5.10. Shuffling an Array 177 5.11. Getting the N Smallest Items of an Array 179 5.12. Building Up a Hash Using Injection 181 5.13. Extracting Portions of Arrays 183 5.14. Computing Set Operations on Arrays 187 5.15. Partitioning or Classifying a Set 189 6. Hashes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 6.1. Using Symbols as Hash Keys 198 6.2. Creating a Hash with a Default Value 199 6.3. Adding Elements to a Hash 201 6.4. Removing Elements from a Hash 203 6.5. Using an Array or Other Modifiable Object as a Hash Key 205 6.6. Keeping Multiple Values for the Same Hash Key 207 6.7. Iterating Over a Hash 208 6.8. Iterating Over a Hash in Insertion Order 211 6.9. Printing a Hash 212 6.10. Inverting a Hash 214 6.11. Choosing Randomly from a Weighted List 216 6.12. Building a Histogram 218 6.13. Remapping the Keys and Values of a Hash 220 6.14. Extracting Portions of Hashes 221 6.15. Searching a Hash with Regular Expressions 222 7. Files and Directories. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 7.1. Checking to See If a File Exists 228 7.2. Checking Your Access to a File 230 7.3. Changing the Permissions on a File 232 7.4. Seeing When a File Was Last Used Problem 235 7.5. Listing a Directory 237 Table of Contents | vii 7.6. Reading the Contents of a File 240 7.7. Writing to a File 244 7.8. Writing to a Temporary File 245 7.9. Picking a Random Line from a File 247 7.10. Comparing Two Files 248 7.11. Performing Random Access on “Read-Once” Input Streams 252 7.12. Walking a Directory Tree 254 7.13. Locking a File 257 7.14. Backing Up to Versioned Filenames 260 7.15. Pretending a String Is a File 263 7.16. Redirecting Standard Input or Output 266 7.17. Processing a Binary File 268 7.18. Deleting a File 272 7.19. Truncating a File 273 7.20. Finding the Files You Want 275 7.21. Finding and Changing the Current Working Directory 277 8. Code Blocks and Iteration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 8.1. Creating and Invoking a Block 282 8.2. Writing a Method That Accepts a Block 284 8.3. Binding a Block Argument to a Variable 287 8.4. Blocks as Closures: Using Outside Variables Within a Code Block 289 8.5. Writing an Iterator Over a Data Structure 291 8.6. Changing the Way an Object Iterates 294 8.7. Writing Block Methods That Classify or Collect 296 8.8. Stopping an Iteration 298 8.9. Looping Through Multiple Iterables in Parallel 300 8.10. Hiding Setup and Cleanup in a Block Method 304 8.11. Coupling Systems Loosely with Callbacks 307 9. Objects and Classes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 9.1. Managing Instance Data 313 9.2. Managing Class Data 316 9.3. Checking Class or Module Membership 319 9.4. Writing an Inherited Class 321 9.5. Overloading Methods 324 9.6. Validating and Modifying Attribute Values 326 9.7. Defining a Virtual Attribute 328 9.8. Delegating Method Calls to Another Object 329 9.9. Converting and Coercing Objects to Different Types 332 9.10. Getting a Human-Readable Printout of Any Object 337 9.11. Accepting or Passing a Variable Number of Arguments 339 viii | Table of Contents 9.12. Keyword Arguments 341 9.13. Calling a Superclass’s Method 343 9.14. Creating an Abstract Method 346 9.15. Freezing an Object to Prevent Changes 348 9.16. Making a Copy of an Object 351 9.17. Declaring Constants 354 9.18. Implementing Class and Singleton Methods 356 9.19. Controlling Access by Making Methods Private 358 10. Modules and Namespaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 363 10.1. Simulating Multiple Inheritance with Mixins 364 10.2. Extending Specific Objects with Modules 367 10.3. Mixing in Class Methods 369 10.4. Implementing Enumerable: Write One Method, Get 48 Free 371 10.5. Avoiding Naming Collisions with Namespaces 375 10.6. Automatically Loading Libraries as Needed 376 10.7. Including Namespaces 378 10.8. Initializing Instance Variables Defined by a Module 380 10.9. Automatically Initializing Mixed-In Modules 381 10.10. Prepending Modules 384 11. Reflection and Metaprogramming. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 11.1. Finding an Object’s Class and Superclass 388 11.2. Listing an Object’s Methods 389 11.3. Listing Methods Unique to an Object 392 11.4. Getting a Reference to a Method 393 11.5. Fixing Bugs in Someone Else’s Class 396 11.6. Listening for Changes to a Class 397 11.7. Checking Whether an Object Has Necessary Attributes 400 11.8. Responding to Calls to Undefined Methods 402 11.9. Automatically Initializing Instance Variables 406 11.10. Avoiding Boilerplate Code with Metaprogramming 408 11.11. Metaprogramming with String Evaluations 410 11.12. Evaluating Code in an Earlier Context 413 11.13. Undefining a Method 414 11.14. Aliasing Methods 417 11.15. Doing Aspect-Oriented Programming 420 11.16. Enforcing Software Contracts 423 12. XML and HTML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429 12.1. Checking XML Well-Formedness 430 12.2. Extracting Data from a Document’s Tree Structure 432 Table of Contents | ix