Ruby

Ruby is a dynamic, object-oriented programming language created by Yukihiro "Matz" Matsumoto in 1995 with an explicit goal: make programmers happy. It reads close to English, favors expressive code, and gives developers powerful tools like blocks, open classes, and metaprogramming. Ruby is best known as the language of Ruby on Rails, which powers GitHub, Shopify, Basecamp, GitLab, and many startups, but it's also used for scripting, DevOps tooling (Homebrew, Chef, Vagrant, Fastlane), and static site generators.

Modern Ruby (3.x) is significantly faster than its reputation suggests, thanks to the YJIT just-in-time compiler, and adds pattern matching, a fiber scheduler for async I/O, Ractors for parallelism, and optional type signatures (RBS).

TL;DR

Quick Example

Idiomatic Ruby: a value object, a module mixin, blocks, Enumerable, and pattern matching:

Core Concepts

Objects and Messages

Every value is an object with methods: 5.times { }, nil.to_a, "hi".upcase. Method calls are messages; respond_to? checks whether an object understands one. Classes are open, so you can add methods to existing classes (monkey patching) — powerful, but best confined to refinements to limit scope.

Blocks, Procs, and Lambdas

A block is a chunk of code passed to a method and called with yield. Procs and lambdas are block objects you can store and pass around; lambdas check argument counts and return from themselves, procs don't. Blocks are how Ruby builds iterators and DSLs:

Modules and Mixins

Modules serve two roles: namespaces (Payments::Stripe) and mixins (include Comparable). Including Enumerable and defining each gives a class dozens of collection methods. Ruby has single inheritance plus any number of mixins.

Duck Typing and Types

Ruby cares whether an object responds to a method, not its class. For larger codebases, RBS signatures with the Steep type checker or Sorbet (Stripe's gradual type checker) add static typing.

Metaprogramming

define_method, method_missing, send, instance_variable_get, and class macros (attr_accessor, Rails' has_many) let code write code. That's how Rails offers concise DSLs — and why heavy metaprogramming can make code hard to trace.

Gems and Bundler

Libraries are gems from RubyGems.org. A Gemfile declares dependencies and Bundler resolves and locks exact versions in Gemfile.lock. Use version managers like rbenv, asdf, or mise to pin Ruby versions per project.

Performance and Concurrency

YJIT, built by Shopify, is a production-ready JIT that often speeds up real Rails apps by 15–30%. Enable it with RUBY_YJIT_ENABLE=1 or --yjit.

Best Practices

Write Idiomatic, Readable Ruby

Prefer Enumerable methods over manual loops, guard clauses over deep nesting, and small methods with clear names. Follow the community style guide and enforce it with RuboCop (or Standard).

Keep Metaprogramming Contained

Use it for well-tested DSLs, not everyday logic. Prefer explicit methods when readability suffers.

Freeze Strings and Constants

# frozen_string_literal: true at the top of files reduces allocations and prevents accidental mutation.

Test Thoroughly

Dynamic typing means tests carry more of the correctness burden. RSpec and Minitest are both mature; add SimpleCov for coverage.

Enable YJIT in Production

It's a low-effort performance win for most applications on Ruby 3.3+.

Move Slow Work to Background Jobs

Sidekiq, GoodJob, or Solid Queue keep web requests fast. See Background Jobs.

Common Mistakes

Global Monkey Patches

Changing core classes globally can break gems in surprising ways. Use refinements or wrapper objects.

N+1 Queries Hidden by Nice Syntax

Elegant Enumerable chains over ActiveRecord associations can fire a query per item. Preload associations.

Relying on method_missing Without respond_to_missing?

Objects then lie about the methods they support, confusing other code and tools.

Expecting Threads to Parallelize CPU Work

The global VM lock serializes Ruby execution. Use processes or Ractors for CPU-bound parallelism.

Unpinned Ruby and Gem Versions

Different Ruby or gem versions across machines cause "works on my machine" bugs. Commit Gemfile.lock and a .ruby-version file.

Comparison

FAQ

What is Ruby used for?

Mostly web development with Ruby on Rails, plus scripting, automation, DevOps tools, static site generators like Jekyll, and mobile build tooling like Fastlane.

Is Ruby still relevant?

Yes. Large companies like Shopify, GitHub, and GitLab run on Ruby, Rails continues to evolve, and Ruby 3.x with YJIT is much faster than earlier versions.

Ruby or Python for beginners?

Both are beginner-friendly. Python has broader use in data science and education; Ruby shines for productive web development with Rails and expressive code.

What's the difference between a block, a proc, and a lambda?

A block is code passed to a method call. A proc is a block turned into an object. A lambda is a stricter proc that checks argument counts and returns from itself rather than the enclosing method.

Does Ruby have static typing?

Not built into the language, but RBS signatures with Steep, or Sorbet, provide gradual static type checking.

Related Topics

References