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. |