Eloquent Ruby, Second Edition
by Russ Olsen
Write better, clearer, more focused Ruby code by becoming truly fluent
in the language. To express yourself eloquently in any language, you
need to go beyond its vocabulary and syntax. Ruby is an easy programming
language to learn, but to gain the fluency needed to write great Ruby
code, you need to break old habits. Start thinking about code the way
experienced Ruby programmers do. Grok how they solve problems. Dig below
the what to the why of Ruby conventions. Thoroughly updated to
reflect modern Ruby usage and with new chapters covering pattern
matching and concurrency, Eloquent Ruby, Second Edition will help you
take advantage of the power and flexibility of the Ruby programming
language.
Writing idiomatic Ruby code is easy: you just have to think like a Ruby
programmer. By explaining the conventions and techniques of Ruby
programming as well as the thinking behind those conventions and
techniques, Eloquent Ruby, Second Edition provides you with the mental
framework to create programs that take full advantage of this powerful
language.
Dive into the core concepts of Ruby programming by starting small and
working through to the bigger ideas. You’ll learn the basics of
formatting Ruby code and then move on to constructing methods, classes,
modules, and tests. From there, you’ll explore more advanced techniques
such as metaprogramming and domain-specific languages. Along the way,
you’ll learn to recognize common Ruby pitfalls and how to avoid them.
You’ll also discover how to use the code behind popular Ruby gems and
Ruby itself as a resource to improve your own code. Completely updated
for Ruby 3.4, the book includes new material on recent additions to Ruby
such as pattern matching and concurrency.
Whether you’re discovering Ruby for the first time or refreshing your
knowledge of a familiar tool, the updated edition of this classic work
will level up your ability to write clear, maintainable, and functional
Ruby.
What You Need
You will need a basic knowledge of the Ruby programming language. To
follow along with the examples in the book, you will need Ruby 3.4.
Resources
Releases:
Note: Contents and extracts of beta books will change as the book is developed.
- Table of
Contents

- Preface

- The Basics
- Write Code That Looks Like Ruby
- Starting With the Basics
- Going Easy on the Comments
- Choosing Camels and Snakes
- Adding and Omitting Parentheses
- Folding Up Those Lines
- Folding Up Those Code Blocks
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Choose the Right Control Structure
- Controlling the Flow of Your Programs
- Use the Modifier Forms Where Appropriate
- Using each, Avoiding for
- Choosing Between Multiple Alternatives
- Tightening Up Your Logic
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Take Advantage of Ruby’s Smart Strings
- Coming Up with a String
- Mastering the String API
- Running Through Your Lines, Characters, and Bytes
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Find the Right String with Regular Expressions
- Matching One Character at a Time
- Discovering Sets, Ranges, and Alternatives
- Embracing the Regular Expression Star
- Using Regular Expressions in Ruby
- Finding the Beginning and the End
- Capturing Your Matches
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Use Symbols to Stand for Something
- Seeing the Two Faces of a String
- Optimizing for Symbolism
- Applying the Rory Test
extract

- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Take Advantage of Ruby’s Smart Collections
- Applying the Literal Shortcuts
- Making Instant Arrays and Hashes from Method Calls
- Running Through Your Collection
- Beware the Bang!
- Relying on the Order of Your Hashes
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Dig Into Your Data With Pattern Matching
extract
- Matching Data Like Strings
- Pattern Matching Arrays
- Capturing Values From Your Pattern Matching
- Pattern Matching Hashes
- Inserting Values Into Your Patterns
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Treat Everything Like an Object—Because Everything Is
- Reviewing the Object Basics
- Seeing Objects Everywhere
- Being an Object
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Understand Dynamic Typing
- Related by Ability
- Extreme Decoupling
- Dealing With the Costs of Dynamic Typing
- Static Typing with RBS and Sorbet
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Write Tests!
- Test Your Code With Minitest
- RSpec: Tests Should be About the Code, Not the Test
- Setting Expectations And Common Values
- Creating the Illusion of Infrastructure
- Creating Objects With An Opinion
- Minitest Specs Back
- Weighing the Testing Alternatives
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Classes, Modules and Blocks
- Construct Your Classes from Short, Focused Methods
- Compressing Specifications
- Composing Methods for Humans
- Composing Ruby Methods
- One Way Out?
- Controlling Access to Your Objects
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Define Operators Respectfully
extract
- Defining Operators in Ruby
- A Sampling of Operators
- Operating Across Classes
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Create Classes That Understand Equality
- Enumerating Ruby Equality
- Double Equals for Everyday Use
- Broadening the Appeal of the == Method
- Working Towards Well-Behaved Equality
- Writing Triple Equals
- Understanding eql?
- Building a Well-Behaved Hash Key
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Get the Behavior You Need with Singleton and Class Methods
- A Double Puzzle
- A Hidden, but Real Class
- Class Methods: Singletons in Plain Sight
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Use Class Instance Variables
- A Quick Review of Class Variables
- Wandering Variables
- Getting Control of the Data in Your Class
- Class Instance Variables and Subclasses
- Adding Some Convenience
- Stashing Your Class Data in Constants
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Use Modules as Name Spaces
- A Place for Your Stuff, with a Name
- A Home for Those Utility Methods
- Building Modules a Little at a Time
- Treat Modules Like the Objects That They Are
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Use Modules as Mixins
- Better Books with Modules
- Mixin Modules to the Rescue
- Extending a Module
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Use Blocks to Iterate
- A Quick Review of Code Blocks
- One Word after Another
- As Many Iterators as You Like
- Iterating over the Ethereal
- Enhance Your Collections With Enumerable
- Make Pseudo-Collections With Enumerator
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Execute Around with a Block
- Add a Little Logging
- When It Absolutely Must Happen
- Setting Up Objects with an Initialization Block
- Dragging Your Scope along with the Block
- Carrying the Answers Back
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Save Blocks to Execute Later
- Making Your Blocks Explicit
- Calling Back From Documents
- Banking Blocks
- Saving Code Blocks for Lazy Initialization
- Creating Instant Block Objects
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Metaprogramming
- Use Hooks to Keep Your Program Informed
- Waking Up to a New Subclass
- Modules Want To Be Heard Too
- Knowing When Your Time Is Up
- Swimming in the Sea of TracePoint
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Use method_missing for Delegation
- Embracing Delegation
- Feeling the Pain of Old-Fashioned Delegation
- Meeting Those Missing Methods
- The method_missing Method to the Rescue
- Creating More Discriminating Delegation
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Use method_missing to Build Flexible APIs
- Building Spam One Word at a Time
- Creating Magic Methods from method_missing
- It’s the Users That Count—All of Them
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Update Existing Classes with Monkey Patching
- Modifying Classes
- Fixing a Broken Class
- Improving Existing Classes
- Renaming Methods with alias_method
- Do Anything to Any Class, Anytime
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Create Self-Modifying Classes
- Thinking About Open Classes, Again
- Putting Programming Logic in Your Classes
- Modifying a Class With Class Methods
- Staying Out of Trouble
- In the Wild
- Wrapping Up
- Create Classes That Modify Their Subclasses
- Enhancing Document
- Subclassing Is (Sometimes) Hard to Do
- Using Class Methods to Build Instance Methods
- Better Method Creation With define_method
- The Modification Sky Is the Limit
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Going Further
- Invent Internal DSLs
- Creating Little Languages for Big Problems
- So Many Files…
- Introducing Rawk
- Stepping Over the DSL Line
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Be Concurrent
- Package Your Programs as Gems
- Consuming Gems
- Gem Versions
- The Nuts and Bolts of Gems
- Building a Gem
- Uploading Your Gem to a Repository
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Know Your Ruby Implementation
- A Fistful of Rubies
- CRuby (AKA MRI): An Enlightening Experience for the C
Programmer
- YARV: MRI with a Byte Code Turbocharger
- JRuby: Bending the “J” in the JVM
- Try Ruby In Your Browser With Opal
- In the Wild
- Staying Out of Trouble
- Wrapping Up
- Remember, Guidelines Not Rules
Author
Russ Olsen is a software engineer, engineering manager, and
compulsive technology explainer. An early adopter of Python, Ruby, and
Clojure, Russ has written three technical books: Eloquent Ruby,
Design Patterns in Ruby, and Getting Clojure, as well as the science
fiction novel Overdrive. Russ is also an occasional conference
speaker: his To The Moon keynote has brought tears to the eyes of
audiences worldwide.