The Well-Grounded Rubyist, Third Edition
David A. Black, Joseph Leo
  • MEAP began November 2017
  • Publication in December 2018 (estimated)
  • ISBN 9781617295218
  • 575 pages (estimated)
  • printed in black & white

This books provides a thorough, in depth introduction to the Ruby programming language.

Chris Schwartz

GET MORE WITH MANNING

An eBook copy of the previous edition, The Well-Grounded Rubyist, Second Edition, is included at no additional cost. It will be automatically added to your Manning Bookshelf within 24 hours of purchase.


The Well-Grounded Rubyist, Third Edition is a perfect tutorial for newcomers to Ruby and a great way for experienced Rubyists to deepen their understanding of the language. This thorough book starts with Ruby fundamentals and offers an in-depth guide to all major language features. In this newly-revised third edition covering Ruby 2.5, expert authors David A. Black and Joe Leo make even familiar concepts seem new and interesting.
Table of Contents detailed table of contents

Part 1: Ruby foundations

1. Bootstrapping your Ruby literacy

1.1. Basic Ruby language literacy

1.1.1. A Ruby syntax survival kit

1.1.2. The variety of Ruby identifiers

1.1.3. Method calls, messages, and Ruby objects

1.1.4. Writing and saving a simple program

1.1.5. Feeding the program to Ruby

1.1.6. Keyboard and file I/O

1.2. Anatomy of the Ruby installation

1.2.1. The Ruby standard library subdirectory (RbConfig::CONFIG[“rubylibdir”])

1.2.2. The C extensions directory (RbConfig::CONFIG[“archdir”])

1.2.3. The site_ruby (RbConfig::CONFIG[“sitedir”]) and vendor_ruby (RbConfig::CONFIG[“vendordir”]) directories

1.2.4. Standard Ruby gems and the gems directory

1.3. Ruby extensions and programming libraries

1.3.1. Loading external files and extensions

1.3.2. “Load”-ing a file in the default load path

1.3.3. “Require”-ing a feature

1.3.4. require_relative

1.4. Out-of-the-box Ruby tools and applications

1.4.1. Interpreter command-line switches

1.4.2. A closer look at interactive Ruby interpretation with irb

1.4.3. ri and RDoc

1.4.4. The rake task-management utility

1.4.5. Installing packages with the gem command

1.5. Summary

2. Objects, methods, and local variables

2.1. Talking to objects

2.1.1. Ruby and object orientation

2.1.2. Creating a generic object

2.1.3. Methods that take arguments

2.1.4. The return value of a method

2.2. Crafting an object: The behavior of a ticket

2.2.1. The ticket object, behavior first

2.2.2. Querying the ticket object

2.2.3. Shortening the ticket code via string interpolation

2.2.4. Ticket availability: Expressing Boolean state in a method

2.3. The innate behaviors of an object

2.3.1. Identifying objects uniquely with the object_id method

2.3.2. Querying an object’s abilities with the respond_to? method

2.3.3. Sending messages to objects with the send method

2.4. A close look at method arguments

2.4.1. Required and optional arguments

2.4.2. Default values for arguments

2.4.3. Order of parameters and arguments

2.4.4. What you can’t do in argument lists

2.5. Local variables and variable assignment

2.5.1. Variables, objects, and references

2.5.2. References in variable assignment and reassignment

2.5.3. References and method arguments

2.5.4. Local variables and the things that look like them

2.6. Summary

3. Organizing objects with classes

3.1. Classes and instances

3.1.1. Instance methods

3.1.2. Overriding methods

3.1.3. Reopening classes

3.2. Instance variables and object state

3.2.1. Initializing an object with state

3.3. Setter methods

3.3.1. The equal sign (=) in method names

3.3.2. Syntactic sugar for assignment-like methods

3.3.3. Setter methods unleashed

3.4. Attributes and the attr_* method family

3.4.1. Automating the creation of attributes

3.4.2. Summary of attr_* methods

3.5. Inheritance and the Ruby class hierarchy

3.5.1. Single inheritance: One to a customer

3.6. Classes as objects and message receivers

3.6.1. Creating class objects

3.6.2. How class objects call methods

3.6.3. A singleton method by any other name…​

3.6.4. When, and why, to write a class method

3.6.5. Class methods vs. instance methods

3.7. Constants up close

3.7.1. Basic use of constants

3.7.2. Reassigning vs. modifying constants

3.8. Nature vs. nurture in Ruby objects

3.9. Summary

4. Modules and program organization

4.1. Basics of module creation and use

4.1.1. A module encapsulating “stacklikeness”

4.1.2. Mixing a module into a class

4.1.3. Using the module further

4.2. Modules, classes, and method lookup

4.2.1. Illustrating the basics of method lookup

4.2.2. Defining the same method more than once

4.2.3. How prepend works

4.2.4. How extend works

4.2.5. The rules of method lookup summarized

4.2.6. Going up the method search path with super

4.2.7. Inspecting method hierarchies with method and super_method

4.3. The method_missing method

4.3.1. Combining method_missing and super

4.4. Class/module design and naming

4.4.1. Mix-ins and/or inheritance

4.4.2. Nesting modules and classes

4.5. Summary

5. The default object (self), scope, and visibility

5.1. Understanding self, the current/default object

5.1.1. Who gets to be self, and where

5.1.2. The top-level self object

5.1.3. Self inside class, module, and method definitions

5.1.4. Self as the default receiver of messages

5.1.5. Resolving instance variables through self

5.2. Determining scope

5.2.1. Global scope and global variables

5.2.2. Local scope

5.2.3. The interaction between local scope and self

5.2.4. Scope and resolution of constants

5.2.5. Class variable syntax, scope, and visibility

5.3. Deploying method-access rules

5.3.1. Private methods

5.3.2. Protected methods

5.4. Writing and using top-level methods

5.4.1. Defining a top-level method

5.4.2. Predefined (built-in) top-level methods

5.5. Summary

6. Control-flow techniques

6.1. Conditional code execution

6.1.1. The if keyword and friends

6.1.2. Assignment syntax in condition bodies and tests

6.1.3. case statements

6.2. Repeating actions with loops

6.2.1. Unconditional looping with the loop method

6.2.2. Conditional looping with the while and until keywords

6.2.3. Looping based on a list of values

6.3. Iterators and code blocks

6.3.1. The ingredients of iteration

6.3.2. Iteration, home-style

6.3.3. The anatomy of a method call

6.3.4. Curly braces vs. do/end in code block syntax

6.3.5. Implementing times

6.3.6. The importance of being each

6.3.7. From each to map

6.3.8. Block parameters and variable scope

6.4. Error handling and exceptions

6.4.1. Raising and rescuing exceptions

6.4.2. The rescue keyword to the rescue!

6.4.3. Raising exceptions explicitly

6.4.4. Capturing an exception in a rescue clause

6.4.5. The ensure clause

6.4.6. Creating your own exception classes

6.5. Summary

Part 2: Built-in classes and modules

7. Built-in essentials

7.1. Ruby’s literal constructors

7.2. Recurrent syntactic sugar

7.2.1. Defining operators by defining methods

7.2.2. Customizing unary operators

7.3. Bang (!) methods and "danger"

7.3.1. Destructive (receiver-changing) effects as danger

7.3.2. Destructiveness and "danger" vary independently

7.4. Built-in and custom to_* (conversion) methods

7.4.1. String conversion: to_s and other methods defined on Object

7.4.2. Array conversion with to_a and the * operator

7.4.3. Numerical conversion with to_i and to_f

7.4.4. Role-playing to_* methods

7.5. Boolean states, Boolean objects, and nil

7.5.1. True and false as states

7.5.2. true and false as objects

7.5.3. The special object nil

7.6. Comparing two objects

7.6.1. Equality tests

7.6.2. Comparisons and the Comparable module

7.7. Inspecting object capabilities

7.7.1. Listing an object’s methods

7.7.2. Querying class and module objects

7.7.3. Filtered and selected method lists

7.8. Summary

8. Strings, symbols, and other scalar objects

8.1. Working with strings

8.1.1. String notation

8.1.2. Basic string manipulation

8.1.3. Querying strings

8.1.4. String comparison and ordering

8.1.5. String transformation

8.1.6. String conversions

8.1.7. String encoding: A brief introduction

8.2. Symbols and their uses

8.2.1. Chief characteristics of symbols

8.2.2. Symbols and identifiers

8.2.3. Symbols in practice

8.2.4. Strings and symbols in comparison

8.3. Numerical objects

8.4. Times and dates

8.4.1. Instantiating date/time objects

8.4.2. Date/time query methods

8.4.3. Date/time formatting methods

8.4.4. Date/time conversion methods

8.5. Summary

9. Collection and container objects

9.1. Arrays and hashes in comparison

9.2. Collection handling with arrays

9.2.1. Creating a new array

9.2.2. Inserting, retrieving, and removing array elements

9.2.3. Combining arrays with other arrays

9.2.4. Array transformations

9.2.5. Array querying

9.3. Hashes

9.3.1. Creating a new hash

9.3.2. Inserting, retrieving, and removing hash pairs

9.3.3. Specifying default hash values and behavior

9.3.4. Combining hashes with other hashes

9.3.5. Hash transformations

9.3.6. Hash querying

9.3.7. Hashes as final method arguments

9.3.8. A detour back to argument syntax: Named (keyword) arguments

9.4. Ranges

9.4.1. Creating a range

9.4.2. Range-inclusion logic

9.5. Sets

9.5.1. Set creation

9.5.2. Manipulating set elements

9.5.3. Subsets and supersets

9.6. Summary

10. Collections central: Enumerable and Enumerator

10.1. Gaining enumerability through each

10.2. Enumerable Boolean queries

10.3. Enumerable searching and selecting

10.3.1. Getting the first match with find

10.3.2. Getting all matches with find_all (a.k.a. select) and reject

10.3.3. Selecting on threequal matches with grep

10.3.4. Organizing selection results with group_by and partition

10.4. Element-wise enumerable operations

10.4.1. The first method

10.4.2. The take and drop methods

10.4.3. The min and max methods

10.5. Relatives of each

10.5.1. reverse_each

10.5.2. The each_with_index method (and each.with_index)

10.5.3. The each_slice and each_cons methods

10.5.4. The slice_ family of methods

10.5.5. The cycle method

10.5.6. Enumerable reduction with inject

10.6. The map method

10.6.1. The return value of map

10.6.2. In-place mapping with map!

10.7. Strings as quasi-enumerables

10.8. Sorting enumerables

10.8.1. Defining sort-order logic with a block

10.8.2. Concise sorting with sort_by

10.8.3. Sorting enumerables and the Comparable module

10.9. Enumerators and the next dimension of enumerability

10.9.1. Creating enumerators with a code block

10.9.2. Attaching enumerators to other objects

10.9.3. Implicit creation of enumerators by blockless iterator calls

10.10. Enumerator semantics and uses

10.10.1. How to use an enumerator’s each method

10.10.2. Protecting objects with enumerators

10.10.3. Fine-grained iteration with enumerators

10.10.4. Adding enumerability with an enumerator

10.11. Enumerator method chaining

10.11.1. Economizing on intermediate objects

10.11.2. Indexing enumerables with with_index

10.11.3. Exclusive-or operations on strings with enumerators

10.12. Lazy enumerators

10.12.1. FizzBuzz with a lazy enumerator

10.13. Summary

11. Regular expressions and regexp-based string operations

11.1. What are regular expressions?

11.2. Writing regular expressions

11.2.1. Seeing patterns

11.2.2. Simple matching with literal regular expressions

11.3. Building a pattern in a regular expression

11.3.1. Literal characters in patterns

11.3.2. The dot wildcard character (.)

11.3.3. Character classes

11.4. Matching, substring captures, and MatchData

11.4.1. Capturing submatches with parentheses

11.4.2. Match success and failure

11.4.3. Two ways of getting the captures

11.4.4. Other MatchData information

11.5. Fine-tuning regular expressions with quantifiers, anchors, and modifiers

11.5.1. Constraining matches with quantifiers

11.5.2. Greedy (and non-greedy) quantifiers

11.5.3. Regular expression anchors and assertions

11.5.4. Modifiers

11.6. Converting strings and regular expressions to each other

11.6.1. String-to-regexp idioms

11.6.2. Going from a regular expression to a string

11.7. Common methods that use regular expressions

11.7.1. String#scan

11.7.2. String#split

11.7.3. sub/sub! and gsub/gsub!

11.7.4. Case equality and grep

11.8. Summary

12. File and I/O operations

12.1. How Ruby’s I/O system is put together

12.1.1. The IO class

12.1.2. IO objects as enumerables

12.1.3. A little more about keyboard input

12.2. Basic file operations

12.2.1. The basics of reading from files

12.2.2. Line-based file reading

12.2.3. Byte- and character-based file reading

12.2.4. Seeking and querying file position

12.2.5. Reading files with File class methods

12.2.6. Writing to files

12.2.7. Using blocks to scope file operations

12.2.8. File enumerability

12.2.9. File I/Oexceptions and errors

12.3. Querying IO and File objects

12.3.1. Getting information from the File class and the FileTest module

12.3.2. Deriving file information with File::Stat

12.4. Directory manipulation with the Dir class

12.4.1. Reading a directory’s entries

12.4.2. Directory manipulation and querying

12.5. File tools from the standard library

12.5.1. The FileUtils module

12.5.2. The Pathname class

12.5.3. The StringIO class

12.5.4. The open-uri library

12.6. Summary

Part 3: Ruby dynamics

13. Object individuation

13.1. Where the singleton methods are: The singleton class

13.1.1. Dual determination through singleton classes

13.1.2. Examining and modifying a singleton class directly

13.1.3. Singleton classes on the method-lookup path

13.1.4. The singleton_class method

13.1.5. Class methods in (even more) depth

13.2. Modifying Ruby’s core classes and modules

13.2.1. The risks of changing core functionality

13.2.2. The risks of changing core functionality

13.2.3. Additive changes

13.2.4. Pass-through overrides

13.2.5. Per-object changes with extend

13.2.6. Using refinements to affect core behavior

13.3. BasicObject as ancestor and class

13.3.1. Using BasicObject

13.3.2. Implementing a subclass of BasicObject

13.4. Summary

14. Callable and runnable objects

14.1. Basic anonymous functions: The Proc class

14.1.1. Proc objects

14.1.2. Procs and blocks and how they differ

14.1.3. Block-proc conversions

14.1.4. Using Symbol#to_proc for conciseness

14.1.5. Procs as closures

14.1.6. Proc parameters and arguments

14.2. Creating functions with lambda and →

14.3. Methods as objects

14.3.1. Capturing Method objects

14.3.2. The rationale for methods as objects

14.4. The eval family of methods

14.4.1. Executing arbitrary strings as code with eval

14.4.2. The dangers of eval

14.4.3. The instance_eval method

14.4.4. Using class_eval (a.k.a. module_eval)

14.5. Parallel execution with threads

14.5.1. Killing, stopping, and starting threads

14.5.2. A threaded date server

14.5.3. Writing a chat server using sockets and threads

14.5.4. Threads and variables

14.5.5. Manipulating thread keys

14.6. Issuing system commands from inside Ruby programs

14.6.1. The system method and backticks

14.6.2. Communicating with programs via open and popen3

14.7. Summary

15. Callbacks, hooks, and runtime introspection

15.1. Callbacks and hooks

15.1.1. Intercepting unrecognized messages with method_missing

15.1.2. Trapping include and prepend operations

15.1.3. Intercepting extend

15.1.4. Intercepting inheritance with Class#inherited

15.1.5. The Module#const_missing method

15.1.6. The method_added and singleton_method_added methods

15.2. Interpreting object capability queries

15.2.1. Listing an object’s non-private methods

15.2.2. Listing private and protected methods

15.2.3. Getting class and module instance methods

15.2.4. Listing objects' singleton methods

15.3. Introspection of variables and constants

15.3.1. Listing local and global variables

15.3.2. Listing instance variables

15.4. Tracing execution

15.4.1. Examining the stack trace with caller

15.4.2. Writing a tool for parsing stack traces

15.5. Callbacks and method inspection in practice

15.5.1. MicroTest background: MiniTest

15.5.2. Specifying and implementing MicroTest

15.6. Summary

16. Ruby and Functional Programming

16.1. Understanding pure functions

16.1.1. Methods with side effects

16.1.2. Pure functions and Referential Transparency in Ruby

16.1.3. Side effects in Ruby’s built-in methods

16.1.4. Modifying an Object’s State

16.2. Immutability

16.2.1. Object#freeze and Object#frozen?

16.2.2. Frozen String Literals

16.3. Higher-order Functions

16.3.1. Method Chaining

16.3.2. Kernel#itself and Kernel#yield_self

16.3.3. Functions that Return Functions

16.3.4. Currying and Partial Function Application

16.4. Recursion

16.4.1. Lazy Evaluation

16.4.2. Tail-call Optimization

16.5. Summary

About the Technology

Ruby is a dynamic language perfect for creating applications, development tools, and administrative scripts. Because it's the backbone of the well-loved Ruby on Rails web framework, Ruby has become one of the most popular programming languages in the world. This elegant language boasts a friendly development community, countless libraries, and amazing productivity tools. Isn't it time you discovered the benefits of being a well-grounded Rubyist?

About the book

The Well-Grounded Rubyist, Third Edition is a beautifully written tutorial that begins with your first Ruby program and takes you all the way to sophisticated topics like reflection, threading, and recursion. Ruby masters David A. Black and Joe Leo distill their years of knowledge for you, concentrating on the language and its uses so you can use Ruby in any way you choose. This Third Edition includes coverage of the latest Ruby features such as the safe navigation operator, method currying, writing side effect-free code, and recursion.

What's inside

  • Fully updated to cover the latest in Ruby 2.5
  • Clear explanations of Ruby concepts and how to apply them
  • Simple examples to seal in the learning
  • Prepares you to use Ruby anywhere for any purpose

About the reader

This book teaches Ruby from the ground up. The reader should have command of basic programming concepts in another language.

About the authors

David A. Black is an internationally-known Ruby developer, author, trainer, speaker, and event organizer, as well as a co-founder of Ruby Central. Joseph Leo III is a Ruby teacher, mentor, and community advocate. He is the lead organizer of the Gotham Ruby Conference (GoRuCo) and founder of Def Method.

Manning Early Access Program (MEAP) Read chapters as they are written, get the finished eBook as soon as it’s ready, and receive the pBook long before it's in bookstores.
buy
The Well-Grounded Rubyist, Third Edition (combo) added to cart
continue shopping
go to cart

MEAP combo $49.99 pBook + eBook + liveBook
The Well-Grounded Rubyist, Third Edition (eBook) added to cart
continue shopping
go to cart

MEAP eBook $39.99 pdf + ePub + kindle + liveBook

FREE domestic shipping on three or more pBooks

Great foundation for becoming a Ruby expert. Basic experience is a plus but not necessary for picking up the language.

Chris Wayman

As a person who loves to understand why things work as they are, this book fulfills my needs and some more.

Pierre-Michel Ansel