What lives here
One unbroken chain of short lessons: every page ends with a link to the
next one, so you can read the course start to finish without ever
wondering where to click. Each lesson teaches one idea with short
Ruby examples; the
introduction and the
basics pages sit next to the course and
cover the same language from the outside.
The course goes from the first script through the core types, collections
and objects, then the standard library, tests, networking, the daily
tools and a pair of small projects. Read the chapters in order the first
time; later, jump to the chapter you need.
Course tree
Every chapter and lesson below is one click away. The Ruby hub shows the same tree together with the introduction, the basics page and the install guides.
ruby ├── Introduction to Ruby ├── Ruby basics: irb, puts and sockets ├── Installing │ ├── Install Ruby on Windows 11 │ ├── Install Ruby on Ubuntu │ ├── Install Ruby on Rocky Linux │ ├── Install Ruby on macOS │ ├── Install Ruby on FreeBSD │ └── Ruby in Docker ├── Getting started │ ├── What is Ruby and where it runs │ ├── Install Ruby and check the version │ ├── irb: the interactive shell │ ├── Your first Ruby script │ ├── Ruby from another language │ ├── irb beyond the prompt │ └── How a Ruby program is put together ├── Core types │ ├── Variables │ ├── Numbers │ ├── Strings │ ├── Symbols │ ├── Truthiness: only false and nil │ ├── nil and object identity │ ├── Mutable, frozen and copied objects │ ├── Integers, floats and rounding │ ├── Formatting strings and numbers │ ├── Constants, globals and scope │ └── Random numbers, ids and tokens ├── Control flow │ ├── Conditions │ ├── Loops │ ├── case and when in depth │ ├── Guard clauses and modifiers │ ├── break, next, redo and retry │ └── &&, ||, and, or and safe navigation ├── Collections │ ├── Arrays │ ├── Hashes │ ├── Ranges │ ├── Enumerables │ ├── Enumerators │ ├── The array toolbox │ ├── The hash toolbox │ ├── Nested arrays and hashes │ ├── Enumerable by task │ ├── Sorting and comparison │ ├── Sets and set operations │ └── Lazy enumerators ├── Methods and blocks │ ├── Methods │ ├── Blocks, procs, lambdas │ ├── Arguments: splats and kwargs │ ├── public, protected and private │ ├── Keyword arguments and forwarding │ ├── Blocks, yield and closures │ ├── Procs, lambdas and method objects │ └── Recursion in Ruby ├── Objects and modules │ ├── Modules and mixins │ ├── Classes and objects │ ├── Inheritance │ ├── Duck typing and core idioms │ ├── Struct and Data │ ├── Comparable and Enumerable in your own class │ ├── Modules as namespaces │ ├── Singleton methods and class << self │ └── Equality and value objects ├── Errors and debugging │ ├── Exceptions │ ├── Debugging │ ├── Exception classes and custom errors │ ├── ensure, at_exit and cleanup │ ├── warn, warnings and log levels │ ├── Debugging with the debug gem │ └── TracePoint, benchmark and profilers ├── Files │ ├── Files and IO │ ├── Reading and writing files │ ├── Paths and directories │ ├── Binary files and streams │ ├── File metadata and permissions │ └── Watching files for changes ├── Text and output │ ├── String tools │ ├── puts, print and p │ ├── ERB templates │ ├── Regular expressions │ ├── Scanning and parsing strings │ ├── A text pipeline │ └── Formatting tables in the terminal ├── Time and encodings │ ├── Encodings │ ├── Time and date │ ├── Time zones and durations │ ├── Parsing and formatting dates │ └── Unicode, bytes and encodings ├── Data formats │ ├── JSON and YAML │ ├── CSV │ ├── YAML in depth │ ├── CSV in depth │ ├── XML and HTML │ └── Configuration files ├── Networking and web │ ├── HTTP clients │ ├── Sockets │ ├── REST APIs │ ├── WEBrick server │ ├── Rails in one lesson │ ├── Net::HTTP in depth │ ├── A REST client that survives │ ├── Rack: what a Ruby web app is │ ├── A web app with Sinatra │ ├── Rails models without the whole app │ ├── Rails controllers and views │ └── A JSON API in Rails ├── Tools and gems │ ├── Gems and Bundler │ ├── Rake tasks │ ├── Environment and CLI │ ├── Logging │ ├── What is inside a gem │ ├── Bundler groups and platforms │ ├── Rake in depth │ ├── A real CLI with OptionParser │ ├── Configuration and environment │ └── Logging in depth ├── Testing │ ├── Testing with Minitest │ ├── Minitest assertions │ ├── Testing a web app │ ├── Minitest in spec style │ ├── Doubles and stubs │ ├── Coverage │ ├── RSpec in one lesson │ └── Testing files and IO ├── Advanced Ruby │ ├── Metaprogramming │ ├── Pattern matching │ ├── Modern Ruby tour │ ├── The object model and method lookup │ ├── method_missing done right │ ├── define_method and small DSLs │ ├── Refinements │ ├── Garbage collection and memory │ ├── Profiling a slow script │ └── Pattern matching in depth ├── Concurrency │ ├── Threads and fibers │ ├── Threads, mutexes and queues │ ├── Processes, fork and signals │ ├── Fibers and the scheduler │ └── Parallel work without a framework ├── CI/CD │ ├── What a CI pipeline is │ ├── Ruby in GitHub Actions │ ├── Ruby in GitLab CI │ ├── Rake as the pipeline runner │ ├── Bundler and the cache │ ├── RuboCop in the pipeline │ ├── Test reports a pipeline can read │ ├── Ruby in Docker images │ ├── Build and release a gem │ ├── Auditing dependencies │ ├── Secrets in a pipeline │ ├── One job, several Ruby versions │ ├── Artifacts against caches │ ├── Automated releases │ ├── Making a pipeline fast │ ├── Security scans │ ├── Deploying from a pipeline │ ├── Ruby tools a pipeline runs │ ├── A pipeline for a CLI gem │ └── A pipeline for a web API ├── Ruby vs Python │ ├── The same program in Ruby and Python │ ├── Text and files in both │ ├── HTTP and JSON in both │ ├── A CLI in both │ ├── Minitest against pytest │ ├── Gems against pip │ ├── Threads in both │ └── The same task, measured └── Projects ├── Capstone: todo CLI ├── Capstone: JSON API ├── Performance ├── Where to go next ├── Project: a log analyzer ├── Project: a link checker ├── Project: CSV to JSON converter ├── Project: package the CLI as a gem └── Project: a pipeline for your own project
How to use this course
Type every example, do not just read it. Run each snippet with
ruby or paste it into
irb before moving on: the course assumes your
hands remember an idea by the time the next chapter arrives.
The usual Ruby rules apply from the first line: two-space indent,
snake_case names, and parentheses left out where
they add no meaning.