| Foreword | p. ix |
| Preface | p. xi |
| Driving Code Through Tests | p. 1 |
| A Quick Note on Testing Frameworks | p. 2 |
| Designing for Testability | p. 2 |
| Testing Fundamentals | p. 10 |
| Well-Focused Examples | p. 10 |
| Testing Exceptions | p. 11 |
| Run the Whole Suite at Once | p. 13 |
| Advanced Testing Techniques | p. 14 |
| Using Mocks and Stubs | p. 14 |
| Testing Complex Output | p. 22 |
| Keeping Things Organized | p. 26 |
| Embedding Tests in Library Files | p. 27 |
| Test Helpers | p. 27 |
| Custom Assertions | p. 29 |
| Conclusions | p. 30 |
| Designing Beautiful APIs | p. 31 |
| Designing for Convenience: Ruport's Table() feature | p. 31 |
| Ruby's Secret Power: Flexible Argument Processing | p. 35 |
| Standard Ordinal Arguments | p. 36 |
| Ordinal Arguments with Optional Parameters | p. 36 |
| Pseudo-Keyword Arguments | p. 37 |
| Treating Arguments As an Array | p. 38 |
| Ruby's Other Secret Power: Code Blocks | p. 40 |
| Working with Enumerable | p. 41 |
| Using Blocks to Abstract Pre- and Postprocessing | p. 43 |
| Blocks As Dynamic Callbacks | p. 45 |
| Blocks for Interface Simplification | p. 47 |
| Avoiding Surprises | p. 48 |
| Use attr_reader, attr_writer, and attr_accessor | p. 48 |
| Understand What method? and method! Mean | p. 50 |
| Make Use of Custom Operators | p. 53 |
| Conclusions | p. 55 |
| Mastering the Dynamic Toolkit | p. 57 |
| BlankSlate: A BasicObject on Steroids | p. 57 |
| Building Flexible Interfaces | p. 62 |
| Making instance_eval() Optional | p. 63 |
| Handling Messages with method_missing() and send() | p. 65 |
| Dual-Purpose Accessors | p. 69 |
| Implementing Per-Object Behavior | p. 70 |
| Extending and Modifying Preexisting Code | p. 74 |
| Adding New Functionality | p. 75 |
| Modification via Aliasing | p. 79 |
| Per-Object Modification | p. 81 |
| Building Classes and Modules Programmatically | p. 84 |
| Registering Hooks and Callbacks | p. 88 |
| Detecting Newly Added Functionality | p. 89 |
| Tracking Inheritance | p. 91 |
| Tracking Mixins | p. 93 |
| Conclusions | p. 96 |
| Text Processing and File Management | p. 99 |
| Line-Based File Processing with State Tracking | p. 99 |
| Regular Expressions | p. 103 |
| Don't Work Too Hard | p. 105 |
| Anchors Are Your Friends | p. 105 |
| Use Caution When Working with Quantifiers | p. 106 |
| Working with Files | p. 109 |
| Using Pathname and FileUtils | p. 109 |
| The tempfile Standard Library | p. 112 |
| Automatic Temporary Directory Handling | p. 113 |
| Collision Avoidance | p. 113 |
| Same Old I/O Operations | p. 114 |
| Automatic Unlinking | p. 114 |
| Text-Processing Strategies | p. 115 |
| Advanced Line Processing | p. 116 |
| Atomic Saves | p. 118 |
| Conclusions | p. 120 |
| Functional Programming Techniques | p. 121 |
| Laziness Can Be a Virtue (A Look at lazy.rb) | p. 121 |
| Minimizing Mutable State and Reducing Side Effects | p. 129 |
| Modular Code Organization | p. 133 |
| Memoization | p. 138 |
| Infinite Lists | p. 145 |
| Higher-Order Procedures | p. 149 |
| Conclusions | p. 152 |
| When Things Go Wrong | p. 153 |
| A Process for Debugging Ruby Code | p. 153 |
| Capturing the Essence of a Defect | p. 157 |
| Scrutinizing Your Code | p. 160 |
| Utilizing Reflection | p. 160 |
| Improving inspect Output | p. 162 |
| Finding Needles in a Haystack | p. 166 |
| Working with Logger | p. 168 |
| Conclusions | p. 176 |
| Reducing Cultural Barriers | p. 177 |
| m17n by Example: A Look at Ruby's CSV Standard Library | p. 178 |
| Portable m17n Through UTF-8 Transcoding | p. 182 |
| Source Encodings | p. 183 |
| Working with Files | p. 183 |
| Transcoding User Input in an Organized Fashion | p. 185 |
| m17n in Standalone Scripts | p. 188 |
| Inferring Encodings from Locale | p. 189 |
| Customizing Encoding Defaults | p. 191 |
| m17n-Safe Low-Level Text Processing | p. 193 |
| Localizing Your Code | p. 195 |
| Conclusions | p. 204 |
| Skillful Project Maintenance | p. 205 |
| Exploring a Well-Organized Ruby Project (Haml) | p. 205 |
| Conventions to Know About | p. 210 |
| What Goes in a README | p. 211 |
| Laying Out Your Library | p. 213 |
| Executables | p. 216 |
| Tests | p. 216 |
| Examples | p. 217 |
| API Documentation via RDoc | p. 219 |
| Basic Documentation Techniques and Guidelines | p. 220 |
| Controlling Output with RDoc Directives | p. 222 |
| The RubyGems Package Manager | p. 227 |
| Writing a Gem::Specification | p. 228 |
| Working with Dependencies | p. 231 |
| Rake: Ruby's Built-in Build Utility | p. 234 |
| Conclusions | p. 237 |
| Writing Backward-Compatible Code | p. 239 |
| Leveraging Ruby's Standard Library | p. 251 |
| Ruby Worst Practices | p. 283 |
| Index | p. 299 |
| Table of Contents provided by Ingram. All Rights Reserved. |