Download PDF
Copied to clipboard
// field guide v 1.0 · Apr 2026

Ruby
Refresher

A field guide for returning Rubyists, built for the rusty.

FOR    Steve Meisner
EVENT Blue Ridge Ruby · Asheville
PREP   Two evenings, one ambition
$ruby --version
ruby 3.4.0 (2024-12-25)

> "matz is nice and so we are nice"
— compiled with love
contents · 14 sections

What's inside

Skim it tonight, dive deeper Friday morning, keep it open in a browser tab between talks. The Time Machine and Cheat Sheet are the highest-leverage sections — read those even if you read nothing else.

  1. 01Time Machinewhat changed since 2008
  2. 02Modern Syntax Cheat Sheetold vs new, side by side
  3. 03Pattern Matching Deep-Divethe biggest leap since blocks
  4. 04Concurrency Modelsthreads vs fibers vs ractors
  5. 05YJIT and the Performance EraRuby is fast now
  6. 06The Library Galaxycanon · niche · curiosities
  7. 07The Modern Rails StackHotwire, Solid, Kamal
  8. 08Phlex, ViewComponent, ERBthe view-layer wars
  9. 09Open Source to Readcode worth studying
  10. 10People to Followyour new feed
  11. 11Conference Survival Kithallway tactics
  12. 12Two-Evening Study Plantonight + Friday morning
  13. 13Glossaryevery word they'll drop
  14. 14Quick Reference Cardtear-out cheat sheet
how to read this
Code blocks are runnable. Try them in irb as you read — muscle memory beats skimming. Anything in red means "this is new since you last touched Ruby seriously."
section 01

01Time Machine

You started in the Ruby 1.8 / Rails 2 era. The world is now Ruby 3.4 and Rails 8. Here's the highlight reel of what landed while you were doing other things.

2008 1.8.7 your era 2009 1.9 {key: val} UTF-8 2013 2.0 kwargs refinements 2019 2.7 _1 _2 pattern (preview) 2020 major 3.0 ractor · pattern endless methods 2022 3.2 YJIT prod Data.define 2023 3.3 Prism parser 2024 today 3.4 it · YJIT++

The five shifts that matter most

  1. Hash syntax flipped. { :name => "Steve" } is now { name: "Steve" }. The rocket is legacy code smell, not your default.
  2. Keyword arguments became real. Method signatures look totally different — def greet(name:, greeting: "hi") with required kwargs is the modern norm.
  3. Pattern matching landed (3.0). case/in destructures hashes and arrays with type and shape constraints. It's the biggest language addition since blocks.
  4. YJIT made Ruby fast. Free 15–40% speedup on real Rails apps with one flag. Shopify runs it at planet scale.
  5. Concurrency story matured. Threads still exist. Fibers + Async became viable for I/O. Ractors exist for true parallelism (still rough).
backwards compat heads-up
Old code in tutorials uses :foo => bar, attr_accessor over Data.define, and bare def foo(opts={}) instead of kwargs. It still works — but if you write it today, eyes will roll.
section 02

02Modern Syntax Cheat Sheet

Old vs new, side by side. If you can read every block on these pages without flinching, you're 80% of the way to "looks fluent in a code review."

Hash literals

# Then
user = { :name => "Steve", :role => :admin }

# Now (2.0+)
user = { name: "Steve", role: :admin }

# Now-now (3.1+) — shorthand pulls from local var
name = "Steve"
role = :admin
user = { name:, role: }

Method arguments

# Then — positional with options hash
def greet(name, opts = {})
  greeting = opts[:greeting] || "hi"
  "#{greeting}, #{name}"
end

# Now — required and optional keyword args
def greet(name:, greeting: "hi")
  "#{greeting}, #{name}"
end

# Anonymous forwarding (3.0+ for blocks, 3.2+ for everything)
def log(...)
  puts caller.first
  inner(...)
end

Safe navigation and one-liners

user&.address&.city            # nil if any link is nil

JSON.parse(str) rescue {}        # one-line rescue

def square(x) = x * x            # endless method (3.0+)

return :ok if all_good?          # trailing conditional, still cool

Block parameter shorthand

%w[hi there].map(&:upcase)       # symbol-to-proc, ages old

[1,2,3].map { _1 * 2 }           # numbered (2.7+)
[1,2,3].map { it * 2 }           # named (3.4+) — preferred now
style note
The Ruby community has settled: it is the future, _1 still works, named params (|x|) win when the variable name adds clarity.

Value objects without the boilerplate

# Then — Struct, mutable by default
Money = Struct.new(:amount, :currency) do
  def +(other) = Money.new(amount + other.amount, currency)
end

# Now — Data is immutable, kwarg-constructed
Money = Data.define(:amount, :currency) do
  def +(other) = with(amount: amount + other.amount)
end

m = Money.new(amount: 10, currency: "USD")
m.amount        # 10
m.amount = 20   # NoMethodError — Data is frozen
m2 = m.with(amount: 99)  # creates a new one

Pattern matching, the headline feature

case api_response
in { status: 200, body: { items: [first, *rest] } }
  process(first, rest)
in { status: (400..499) => code, body: { error: String => msg } }
  raise ClientError.new(code, msg)
in { status: 500.. }
  retry_later
end

# Rightward assignment — pull a value out of a hash
{ name: "Steve", role: :admin } => { name:, role: }
puts name   # "Steve"

# In-line check — returns true/false
{ a: 1, b: 2 } in { a: Integer }   # => true

Iteration helpers you should know

"hello world".chars.tally
# => {"h"=>1, "e"=>1, "l"=>3, "o"=>2, " "=>1, "w"=>1, "r"=>1, "d"=>1}

[1, 2, 3, 4].sum { |n| n * n }      # 30

%w[a b c d].each_cons(2).to_a       # => [["a","b"], ["b","c"], ["c","d"]]
%w[a b c d].each_slice(2).to_a      # => [["a","b"], ["c","d"]]

# Lazy for huge or infinite sequences
(1..Float::INFINITY).lazy
  .map  { it ** 2 }
  .select { it.even? }
  .first(5)
# => [4, 16, 36, 64, 100]

# Hash with default block — the "group by" pattern
groups = Hash.new { |h, k| h[k] = [] }
words.each { groups[it.length] << it }

Tap and then for fluent chains

User.new(params)
  .tap(&:save)                       # side effect, returns self
  .then { Mailer.welcome(it) }       # transform, returns new value
  .deliver_later
section 03

03Pattern Matching, Deep

The single feature most likely to confuse you mid-talk. Worth 20 minutes of focused study because once it clicks, it changes how you write Ruby.

The shape of it

Three forms exist. Memorize them all.

# 1. case/in — full branching
case value
in Integer => n if n > 0
  "positive int #{n}"
in [String, *]
  "array starting with a string"
in { status: 200 }
  "ok"
else
  "no match"
end

# 2. Rightward assignment — assert and destructure (raises NoMatchingPatternError)
{ name: "Steve", age: 47 } => { name:, age: }

# 3. Boolean test — returns true/false
{ status: 200 } in { status: Integer }   # => true

Patterns you can match

PatternExampleWhat it means
Literalin 200Exact value
Classin String=== against the class
Rangein 200..299Includes value
Arrayin [1, 2, *rest]Shape match, captures rest
Hashin { status:, body: }Has these keys, binds them
Findin [*, Integer => n, *]Has at least one Integer
Capturein Integer => nBind matched value to n
Pinin ^expectedCompare to outer var (don't bind)
Alternativein 1 | 2 | 3Any of these
Guardin Integer => n if n.even?Pattern AND condition

Custom deconstruction

Any object can opt into pattern matching by defining deconstruct (for arrays) or deconstruct_keys (for hashes).

class Point
  attr_reader :x, :y
  def initialize(x, y) = (@x, @y = x, y)
  def deconstruct       = [x, y]
  def deconstruct_keys(keys) = { x:, y: }
end

p = Point.new(3, 4)

case p
in [0, 0]            then "origin"
in { x: 0 }          then "on y-axis"
in { x:, y: } if x == y then "diagonal"
in [Integer, Integer] then "anywhere else"
end
when to reach for it
Pattern matching shines when you're shaping data: API responses, JSON parsing, AST walking, message dispatch. For simple if/else you don't need it. For deeply nested hash extraction, it's a superpower.
section 04

04Concurrency Models

Ruby has three primitives for doing more than one thing at once. They're not interchangeable. Knowing which to reach for is a marker of fluency.

Thread os-managed · GIL-bound GVL Use for I/O-bound work — DB queries, HTTP calls Watch out CPU work won't go in parallel — GVL holds Fiber cooperative · scheduler-driven run yield resume yield done single thread, many fibers Use for 10K+ concurrent I/O connections (Async) Watch out Blocking calls block all fibers in thread Ractor isolated · truly parallel ractor 1 ractor 2 ractor 3 message-passing only Use for CPU-bound parallel work that can be sharded Watch out Still experimental. Most gems aren't safe.

The pragmatic guidance

For 99% of Rails code, you'll never write a thread, fiber, or ractor by hand — Puma uses threads, Falcon uses fibers, Sidekiq has a worker pool. You just need to know which model your tools use, so you don't fight them.

# Async — the modern way to do concurrent I/O
require 'async'
require 'async/http/internet'

Async do
  internet = Async::HTTP::Internet.new
  urls = %w[https://a.com https://b.com https://c.com]

  results = urls.map do |url|
    Async { internet.get(url).read }   # fires off concurrently
  end.map(&:wait)
end
section 05

05YJIT & The Performance Era

If a 2014-era Rubyist time-traveled to today, the most shocking thing wouldn't be the syntax — it'd be how fast Ruby got.

What YJIT is

YJIT (Yet-another-just-in-time-compiler) is a JIT compiler written in Rust, built into Ruby itself since 3.1. It watches your code as it runs and compiles hot paths to native machine code. It was developed at Shopify and runs in production on every Shopify storefront.

WorkloadTypical YJIT speedupNotes
Rails app, real traffic15–40%Shopify reports ~15% latency drop
CPU-heavy benchmarks2–4×Optcarrot, railsbench
Tiny scriptsoften slowerCompile cost not amortized

Turning it on

# CLI flag
ruby --yjit script.rb

# Env var
RUBY_YJIT_ENABLE=1 bundle exec rails server

# In code
RubyVM::YJIT.enable

# In Rails (config/environments/production.rb)
config.yjit = true   # default in Rails 7.2+

Other speed wins worth knowing

Frozen string literals

# frozen_string_literal: true   # magic comment, top of file

# Every string literal is frozen — no allocation on repeat use
def status_label = "active"   # one String object, forever

Bootsnap

Shopify gem (bundled with Rails) that caches compiled code, autoload paths, and YAML. Cuts Rails boot time by 50%+ on cold starts.

Fast JSON, fast everything

oj (Optimized JSON) is 4–8× faster than stdlib JSON. brotli for compression. nokogiri for XML/HTML. The Ankane gems are reliably fast.

conf-floor talking point
"Are you on YJIT?" is a perfectly normal question to ask anyone running Rails in production today. If they say no, the follow-up is "any blocker?" — usually it's just "haven't gotten to it."
section 06

06The Library Galaxy

A field map of gems by orbit: the inner planets you'll see in every app, the outer-belt specialists, and the comets — weird and wonderful.

Ruby 3.4 Rails Sidekiq RSpec Puma Hotwire Solid Kamal Phlex dry-rb Hanami Sequel Roda Async Falcon canonical Rails 8 stack alt frameworks specialist / niche

The canon — every Rails dev knows these

GemWhat it doesNotes
RailsFull-stack web frameworkv8 is current; "no PaaS required" defaults
SidekiqBackground jobs (Redis)Mike Perham; Pro/Ent funds the open core
Solid QueueBackground jobs (Postgres/SQLite)Rails 8 default — eating Sidekiq's lunch
DeviseAuthenticationOld guard, still everywhere
RodauthAuthenticationModern, secure, gaining ground over Devise
PunditAuthorization (policies)Tiny, idiomatic
RSpecTesting DSLMost common in apps; describe/context/it
MinitestTesting (Rails default)Faster, simpler, fewer abstractions
FactoryBotTest data factoriesWas factory_girl
RubocopLinter / formatterOften paired with standard for style
PumaApp server (threaded)Default in Rails
NokogiriHTML/XML parsingFoundational; ships with Rails
PagyPaginationReplaced Kaminari for many; very fast
BulletN+1 query detectionDev-only must-have

The "modern Rails" power-ups

GemWhat it does
HotwireTurbo + Stimulus — HTML-over-the-wire, "no SPA needed"
ViewComponentGitHub's component framework — server-rendered Ruby objects
PhlexHTML in Ruby. def view_template; h1 { "Hi" }; end
LookbookVisual component browser for ViewComponent / Phlex
KamalDHH's deploy tool — Docker + SSH, no Kubernetes
PropshaftNew asset pipeline — Sprockets is on the way out
importmap-railsShip JS without a bundler. Rails 7+ default.
LitestackSQLite-as-everything (queue, cache, pub/sub) — buzzy

The dry-rb & functional Ruby orbit

A whole parallel ecosystem favoring small, composable objects over Rails-y conventions. Common at Stripe, Shopify, and shops that came out of the Trailblazer school.

GemWhat it does
dry-validationSchema validation — declarative, composable
dry-monadsSuccess/Failure, Maybe, do-notation
dry-typesType system for Ruby objects
ROM (Ruby Object Mapper)Alt to ActiveRecord — repository pattern
SequelThe other great ORM. Often better than AR for complex SQL.
RodaRouting-tree microframework. Beautifully designed.
HanamiFull alternative to Rails — dry-rb-flavored, slice-based

Specialists, niche gems, and curiosities

Async

github.com/socketry/async · Samuel Williams

Structured concurrency for Ruby. The future of high-concurrency I/O. Powers Falcon webserver.

Falcon

github.com/socketry/falcon

Async-based webserver. Tens of thousands of concurrent connections per process.

Polars-rb

github.com/ankane/polars-ruby

DataFrames in Ruby, Rust-backed. Very fast.

pgvector-ruby

github.com/pgvector/pgvector-ruby

Vector embeddings in Postgres — the "I have an LLM in my Rails app" gem.

langchainrb

github.com/patterns-ai-core/langchainrb

LLM agents and RAG in Ruby. Small but real ecosystem.

Sorbet

sorbet.org · Stripe

Gradual type checker. Used at Shopify, Stripe, GitHub. RBS+Steep is the official alt.

Avo

avohq.io

Modern admin panel framework. Beautiful out of the box.

GoodJob

github.com/bensheldon/good_job

Postgres-backed background jobs. Pre-cursor to Solid Queue, still excellent.

Bridgetown

bridgetownrb.com

Modern Jekyll. Static sites, Ruby-flavored.

StimulusReflex

stimulusreflex.com

Reactive Rails before Hotwire. Niche but loved.

section 07

07The Modern Rails Stack

Rails 8 is opinionated about the whole stack now — front to back, deploy included. Here's what a "fresh rails new" gives you in 2026.

Browser renders HTML user View Layer ERB · ViewComponent · Phlex · Turbo Frames + Streams · Stimulus Hotwire Controller / Routing ActionController · ActionDispatch · Rack middleware Rails core Model ActiveRecord · Concerns · Encryption · Multi-DB domain Background Solid Queue · Solid Cable · Solid Cache Storage PostgreSQL · SQLite · ActiveStorage Deploy Kamal · Docker · "no PaaS required"

Hotwire decoded

PieceWhat it actually is
Turbo DriveIntercepts links/forms, swaps the <body> without a full reload. Like Rails' old Turbolinks but better.
Turbo FramesLazy-load & replace a chunk of HTML. <turbo-frame id="cart"> updates independently.
Turbo StreamsServer pushes HTML over WebSocket / SSE. <turbo-stream action="append" target="messages">
StimulusTiny JS framework. Controllers attach via data-controller="...". Sprinkles, not SPA.
NativeiOS/Android adapters that wrap your Hotwire app in a thin native shell. (How HEY ships.)

The Solid trio

Rails 8 ships Solid Queue, Solid Cache, and Solid Cable — Postgres-or-SQLite-backed implementations of background jobs, caching, and websockets. The narrative: you don't need Redis to run a Rails app anymore. (You can still use Redis. Many do.)

why this matters
The Solid trio + Kamal + SQLite is DHH's "you can self-host on a single VPS" pitch. It's a real shift — small Rails apps no longer need Heroku-style PaaS or 5 services. Big ones still benefit from Redis & managed infra.
section 08

08Phlex, ViewComponent, ERB

The view layer is where Ruby has the most active aesthetic debate right now. You'll hear all three names. Here's what each one looks like.

ERB — the classic

<!-- app/views/users/show.html.erb -->
<h1><%= @user.name %></h1>
<ul>
  <% @user.posts.each do |post| %>
    <li><%= link_to post.title, post %></li>
  <% end %>
</ul>

ViewComponent — server-rendered components

# app/components/user_card_component.rb
class UserCardComponent < ViewComponent::Base
  def initialize(user:)
    @user = user
  end

  def admin? = @user.role == :admin
end

# app/components/user_card_component.html.erb
<div class="card <%= 'admin' if admin? %>">
  <h3><%= @user.name %></h3>
</div>

# Use it
<%= render UserCardComponent.new(user: @user) %>

Phlex — HTML in pure Ruby

class UserCard < Phlex::HTML
  def initialize(user:)
    @user = user
  end

  def view_template
    div(class: card_class) do
      h3 { @user.name }
      p { "Joined #{@user.created_at.to_date}" }
      a(href: user_path(@user)) { "View profile →" }
    end
  end

  private

  def card_class
    @user.admin? ? "card admin" : "card"
  end
end

# In a controller / view
render UserCard.new(user: @user)

Choosing between them

Best forWatch out
ERBMost apps, most pages. The default for a reason.Logic-in-template creep over time.
ViewComponentReusable UI in a design system. Big team apps.Boilerplate per component (two files).
PhlexDevs who think in Ruby and dislike template languages. Highly composable UI.Smaller community. ERB tutorials don't translate.
conf weather report
Phlex is hot — talks about it appear at every Ruby conf in 2025–26. ViewComponent is mature and dominant in big shops. ERB is still 90%+ of all Rails templates. None of these are going away.
section 09

09Open Source to Read

Reading great Ruby is the fastest way to absorb modern style. Here's a curated tour, ordered easiest-to-hardest.

Read for code quality & idioms

Pagy small

github.com/ddnexus/pagy

~1k lines. Read the whole thing. Masterclass in keeping a gem tiny while doing one thing well.

Sidekiq medium

github.com/sidekiq/sidekiq

Mike Perham. Production-grade Ruby. Notice the lack of meta-magic and the comments.

Sequel deep

github.com/jeremyevans/sequel

Jeremy Evans. A masterclass in Ruby library design. Plugins-as-modules pattern.

Roda deep

github.com/jeremyevans/roda

Routing-tree microframework. Every line considered. Read alongside Rails for contrast.

dry-rb gems style

github.com/dry-rb

Exemplars of small-object, functional-flavored Ruby. Different aesthetic from Rails.

Phlex small

github.com/phlex-ruby/phlex

Joel Drapper's HTML-in-Ruby. See how a modern DSL is built today.

Read to see real apps

Lobsters beginner

github.com/lobsters/lobsters

Tiny HN-style site. Small enough to grok in an afternoon. Classic Rails patterns.

Discourse huge

github.com/discourse/discourse

Forum software. Modern Rails, ambitious frontend, heavily commented. Sam Saffron writes great Ruby.

Mastodon huge

github.com/mastodon/mastodon

Federated social. Rails + ActivityPub. Real-world distributed systems in Ruby.

Forem huge

github.com/forem/forem

The dev.to engine. Classic Rails monolith, well-tended.

Chatwoot medium

github.com/chatwoot/chatwoot

Customer support platform. Good showcase of WebSockets / ActionCable in production.

Solidus deep

github.com/solidusio/solidus

E-commerce. Complex domain modeling — pricing, inventory, fulfillment.

how to read code well
Don't read top-to-bottom. Pick a single feature ("how does Lobsters do voting?"), find its controller, then trace down: model → service object → tests. Forty minutes of one feature beats four hours of skimming.
section 10

10People to Follow

The Ruby community is small, friendly, and remarkably accessible. These are the names you'll hear referenced in talks and hallway chats.

Core & legends

NameKnown forWhere
Yukihiro Matsumoto (Matz)Created Ruby. Still active, still nice.@yukihiro_matz
DHH (David Heinemeier Hansson)Created Rails. 37signals. Opinionated.@dhh · world.hey.com/dhh
Aaron Patterson (tenderlove)Rails core. Performance. Hilarious.@tenderlove · tenderlovemaking.com
Eileen UchitelleRails core. Multi-database. GitHub.@eileencodes
Xavier Noria (fxn)Zeitwerk autoloader. Deep Ruby internals.@fxn
Koichi Sasada (ko1)YARV, Ractor, GC.atdot.net/~ko1

Library authors worth following

NameBuilt
Mike PerhamSidekiq · mikeperham.com
Jeremy EvansSequel, Roda, Rodauth
Andrew Kane (ankane)Searchkick, PgHero, Lockbox, dozens of gems
Samuel Williams (ioquatix)Async, Falcon — the future of Ruby I/O
Sam SaffronDiscourse co-founder. Performance writer.
Joel DrapperPhlex creator
Stephen MargheimSQLite-on-Rails evangelist
Bozhidar Batsov (bbatsov)Rubocop, The Ruby Style Guide
Noah Gibbs"Rebuilding Rails" book, benchmarking

Newsletters & podcasts

section 11

11Conference Survival Kit

Ruby people are some of the friendliest in tech. The community has a strong "Matz is nice and so we are nice" (MINASWAN) ethos. Lean into it.

Hallway track tactics

Conversation starters that work

try these

If a talk goes over your head

  1. Don't panic. Half the room is faking it too.
  2. Write down the vocabulary, not the content. Look it up after.
  3. Find the speaker after — speakers love "I didn't fully follow X but it sounded important; can you point me at a starter resource?"
  4. Check the talk's slides/repo on the conference website afterward — most Ruby speakers post code/slides publicly.

The vocabulary survival list

If someone uses one of these and you blank, here's the 6-second mental cache:

If they say...You think...
"We Kamal'd it"Deployed via DHH's Docker+SSH tool
"Just throw it on a Solid Queue job"Background job, Postgres-backed, Rails 8 default
"It's a Phlex component"HTML written in Ruby methods, no template file
"We're on YJIT"Ruby's JIT compiler, free perf
"That's a Turbo Stream"Server pushing HTML over WebSocket/SSE
"Use a Sorbet sig"Stripe's gradual type checker
"It's a Ractor"Isolated parallel actor (Ruby 3+)
"Bundler issue"Gemfile dependency problem
"Zeitwerk's complaining"Rails autoloader; usually file/class name mismatch
section 12

12Two-Evening Study Plan

Designed for tonight + Friday morning before the conf opens. ~2 hours total. Don't aim for fluency — aim for recognition.

Tonight (~90 min)

  1. Read sections 01–03 of this guide (Time Machine, Cheat Sheet, Pattern Matching). ~25 min
  2. Open irb and type every code block from Section 02. Don't paste — type. Muscle memory beats reading. ~30 min
  3. Solve one pattern-matching exercise. Open a scratch file:
    # Given an API response shape like:
    #   { status: 200|400|500, body: { ... } | { error: "..." } }
    # write a method that returns:
    #   :ok | :client_error | :server_error
    # using ONE case/in statement.
    ~15 min
  4. Skim sections 06–08 (libraries, Rails stack, view layer wars). Don't memorize — just absorb the shape. ~20 min

Friday morning (~30 min)

  1. Re-skim Section 11 (Conference Survival Kit) on the way to the venue. ~10 min
  2. Read one Hotwire example — the Turbo handbook intro on hotwired.dev. ~10 min
  3. Pick the talk that scares you most from the schedule. Read its abstract carefully and Google any unfamiliar word. ~10 min

During the conf

"You don't need to understand everything. You need to recognize enough to ask the next question."
section 13

13Glossary

Every term you might hear, with a one-sentence definition. Bookmark this page; refer often.

A — H

ActionCable — Rails' WebSocket framework.

ActionMailer — Rails' email framework.

ActionText — Rich-text editing in Rails (uses Trix).

ActiveJob — Rails' background-job abstraction; backends include Sidekiq, Solid Queue, GoodJob.

ActiveRecord — Rails' ORM.

ActiveSupport — Ruby stdlib extensions Rails ships (e.g. blank?, presence).

Async — Samuel Williams' concurrency gem; structured fibers.

Bootsnap — Caches compiled Ruby + autoload paths for fast boot.

Bundler — Dependency manager. Gemfile + Gemfile.lock.

Concern — Module mixin pattern; extend ActiveSupport::Concern.

Crystal — Compiled language with Ruby-like syntax. Not Ruby.

Data.define — Immutable value object class (Ruby 3.2+).

DSL — Domain-specific language. Ruby's superpower (RSpec, routes).

dry-rb — A suite of small functional gems (validation, monads, types).

Endless methoddef foo = bar (Ruby 3.0+).

Falcon — Async-based webserver.

Fiber — Cooperative lightweight thread.

Frozen string literals — Magic comment that freezes all string literals. Faster.

Gemfile — Bundler dependency declaration.

GVL — Global VM Lock. One thread runs Ruby code at a time.

Hanami — Alternative web framework, dry-rb-flavored.

Hotwire — Turbo + Stimulus, the "no SPA" Rails frontend.

I — Z

importmap — Ship JS without a bundler. Rails 7+ default.

Kamal — DHH's Docker-based deploy tool.

kwargs — Keyword arguments. def f(name:).

Minitest — Rails' default test framework.

mruby — Embedded Ruby (IoT, robotics).

Pattern matchingcase/in destructuring (Ruby 3+).

Phlex — HTML in Ruby instead of ERB.

Prism — New Ruby parser, written in C, default in 3.4.

Propshaft — New asset pipeline replacing Sprockets.

Puma — Default Rails app server, threaded.

Rack — Foundational web server interface (every Ruby web framework is Rack-based).

Ractor — Actor-based parallel execution unit (Ruby 3+, experimental).

RBS — Official Ruby type signature format.

Roda — Routing-tree microframework (Jeremy Evans).

Sidekiq — Redis-backed background job system.

Solid Cache / Cable / Queue — Rails 8's Postgres/SQLite-backed cache, websockets, jobs.

Sorbet — Stripe's gradual type checker.

Sprockets — Old asset pipeline, being replaced by Propshaft.

Stimulus — Tiny JS sprinkles framework (part of Hotwire).

Turbo Drive — Intercepts navigation, swaps body without reload.

Turbo Frame — Independently-updatable HTML chunk.

Turbo Stream — Server-pushed HTML over WebSocket/SSE.

ViewComponent — GitHub's component framework.

YARV — Yet Another Ruby VM. The bytecode interpreter.

YJIT — Ruby's JIT compiler. Written in Rust.

Zeitwerk — Rails' autoloader. Filename → class name.

section 14 · tear-out

14Quick Reference Card

The minimum-viable cheat sheet. Print this page if nothing else; it covers ~90% of what you'll see in a modern Rails codebase.

Hash & kwargs

{ name: "x", role: :admin }
{ name:, role: }              # 3.1+
def f(name:, age: 18); end
def f(...); inner(...); end

Blocks

arr.map(&:upcase)
arr.map { it * 2 }            # 3.4+
arr.map { _1 * 2 }            # 2.7+
arr.each_with_object({}) { |x, h| h[x] = x.size }

Safe nav & rescue

user&.address&.city
JSON.parse(s) rescue {}
def square(x) = x * x

Pattern matching

case x
in Integer => n if n > 0
in [a, *rest]
in { status: 200, body: }
end

x in { ok: true }              # boolean
{a:1} => { a: }                # destructure

Data & Struct

Money = Data.define(:amt, :cur)
m = Money.new(amt: 5, cur: "USD")
m.with(amt: 10)               # new copy

Enumerable hits

arr.tally
arr.sum { it * 2 }
arr.each_cons(2)
arr.each_slice(3)
arr.partition(&:even?)
hash.transform_values { it * 2 }
hash.filter_map { |k, v| k if v > 0 }

Lazy

(1..).lazy.select(&:prime?).first(10)

Chains

obj.tap(&:save)            # side effect
   .then { wrap(it) }      # transform

Modern Rails command flags

rails new app --css=tailwind \
              --javascript=importmap \
              --database=sqlite3
bundle exec rails db:migrate
RUBY_YJIT_ENABLE=1 bundle exec puma

Top 10 conf vocabulary

Hotwire · Turbo Frame/Stream · Stimulus · Solid Queue · Solid Cache · Solid Cable · Kamal · Phlex · ViewComponent · YJIT


end of guide

Have a great conference, Steve. Bring back gossip.