
Ruby
First appeared 1995 · Yukihiro Matsumoto
Optimised for programmer happiness — and, with Rails, for shipping a product faster than anyone expects.
Overview
Ruby is a dynamic, open-source, object-oriented programming language with a strong focus on simplicity, productivity, and developer happiness. Created by Yukihiro 'Matz' Matsumoto in Japan in the mid-1990s, Ruby was designed with the explicit philosophy that programming should be enjoyable and that the language should prioritize human needs over computer needs. Ruby emphasizes elegant, natural, and human-friendly syntax that reads almost like English, making code easy to write, read, and understand. It's a pure object-oriented language where absolutely everything is an object, including primitive types like numbers and booleans, providing remarkable consistency in how you interact with different data types. Ruby supports multiple programming paradigms including procedural, object-oriented, and functional programming, giving developers flexibility in how they approach problems. The language is best known for Ruby on Rails, the revolutionary web application framework that transformed web development in the mid-2000s with its convention-over-configuration philosophy, emphasis on developer productivity, and elegant approach to building database-backed web applications. Ruby features automatic memory management through garbage collection, dynamic typing that allows for flexible and expressive code, powerful metaprogramming capabilities that enable developers to write code that writes code, blocks and closures as first-class language features, mixins through modules for sharing behavior across classes without traditional inheritance, and an elegant syntax for everything from string interpolation to regular expressions. The language includes a comprehensive standard library covering file I/O, networking, data structures, and much more, plus a rich ecosystem of gems (Ruby's term for libraries and packages) distributed through RubyGems, the package manager that makes it trivial to share and use code. Ruby's syntax is remarkably clean and expressive, often allowing developers to accomplish in a few lines what might take many more in other languages, without sacrificing readability. The language emphasizes the principle of least surprise, meaning it should behave in a way that minimizes confusion for experienced users, though this is balanced with Matz's philosophy that the language should be optimized for programmer happiness. Ruby has powerful features like duck typing (if it walks like a duck and quacks like a duck, it's a duck), open classes that allow you to modify existing classes including built-in ones, symbols for efficient string-like identifiers, and a flexible syntax that often makes parentheses and other punctuation optional. The language has excellent support for text processing, making it popular for scripting and automation tasks, and its expressiveness makes it a favorite for domain-specific languages (DSLs). Ruby's community is known for being friendly, welcoming, and focused on best practices, with a strong emphasis on testing, clean code, and continuous improvement. The language has influenced many other languages and frameworks, and its philosophy of developer happiness has shaped how many programmers think about language design and software development.
Key facts
The reference details, without the paragraph.
- First appeared
- 1995
- Designed by
- Yukihiro 'Matz' Matsumoto
- Typing
- Dynamic, strong and duck-typed, with optional type signatures via RBS and Sorbet
- Execution
- Compiled to bytecode for the YARV virtual machine, with the YJIT just-in-time compiler
- Memory model
- Automatic — generational, incremental, compacting garbage collection
- Package manager
- RubyGems with Bundler
- File extensions
- .rb, .rake, .gemspec
- Current line
- Ruby 3.x, with a release every December
- Design principle
- The principle of least surprise — the language should behave as you expect
- Licence
- Ruby License and BSD 2-clause
History
How the language got here — the decisions that still shape how you write it.
Ruby was created by Yukihiro Matsumoto, affectionately known as 'Matz' in the Ruby community, in Japan in the mid-1990s, with the first public release (version 0.95) on December 21, 1995. Matz began working on Ruby on February 24, 1993, motivated by his dissatisfaction with existing scripting languages and his desire to create a language that would make programming more enjoyable. He wanted to create a language that was more powerful and object-oriented than Perl, more elegant and consistent than Python, and more fun to use than any existing language. Matz drew inspiration from his favorite programming languages, combining features from Perl (text processing and regular expressions), Smalltalk (pure object-oriented design and message passing), Eiffel (design by contract concepts), Ada (exception handling), and Lisp (functional programming features and powerful metaprogramming). The name 'Ruby' was chosen as a gemstone name, following the tradition of Perl (which sounds like 'pearl'), and because it was the birthstone of one of Matz's colleagues. Ruby was also chosen because it comes after Perl in several contexts (ruby is more valuable than pearl, and Ruby comes after Perl alphabetically). For its first several years, Ruby remained relatively unknown outside of Japan, where it developed a dedicated following and was used for various applications. The language evolved through the late 1990s and early 2000s with incremental improvements, but remained largely a Japanese phenomenon with limited English documentation. The turning point for Ruby came in 2004-2005 with the emergence of Ruby on Rails, a web application framework created by David Heinemeier Hansson (DHH) while building Basecamp, a project management application. Rails was extracted from Basecamp and released as open-source software in July 2004, with version 1.0 arriving in December 2005. Ruby on Rails revolutionized web development with its convention-over-configuration approach, which eliminated much of the boilerplate code required in other frameworks, its emphasis on RESTful design, its integrated testing framework, its database migrations for managing schema changes, and its overall philosophy of developer happiness and productivity. Rails demonstrated that you could build sophisticated web applications rapidly without sacrificing code quality or maintainability. The framework's success was phenomenal, sparking what became known as the 'Rails revolution' and bringing Ruby into the international spotlight. Suddenly, developers around the world were learning Ruby specifically to use Rails, and the language's popularity exploded. This period saw the emergence of numerous Ruby conferences, user groups, books, tutorials, and a vibrant global community. The success of Rails also validated Ruby's design philosophy, showing that a language optimized for developer happiness could lead to remarkable productivity gains. Ruby's growth led to increased attention to performance and scalability. Ruby 1.8, which was the version when Rails emerged, was relatively slow compared to other languages. The community responded with several initiatives: JRuby (Ruby implemented on the Java Virtual Machine), Rubinius (Ruby implemented in Ruby itself with a custom VM), and most significantly, the development of Ruby 1.9, which included YARV (Yet Another Ruby VM), a new bytecode interpreter that significantly improved performance. Ruby 1.9, released in 2007 with a stable version in 2009, brought major improvements including better performance, improved Unicode support, new syntax features, and a more robust standard library. Ruby 2.0, released in 2013 on the language's 20th anniversary, continued this evolution with keyword arguments, refinements for safer monkey-patching, and other improvements. Subsequent versions (2.1, 2.2, 2.3, etc.) brought incremental performance improvements and new features. Ruby 3.0, released on Christmas Day 2020 (25 years after Ruby's initial release), was a major milestone with the goal of being 3x faster than Ruby 2.0, introducing a JIT compiler, improved concurrency with Ractor (Ruby's actor-model implementation), type signatures through RBS, and many other enhancements. Throughout its history, Ruby has powered numerous significant applications and companies. GitHub, the world's largest code hosting platform, was built with Ruby on Rails and remains largely Rails-based. Shopify, one of the largest e-commerce platforms, is built on Rails and has become one of the biggest contributors to Ruby and Rails development. Basecamp, the project management tool that spawned Rails, continues to be built with Rails. Airbnb, Twitch, Hulu, and countless other companies have used Ruby and Rails for their web applications. The Ruby community has been instrumental in advancing software development practices, particularly around testing (with tools like RSpec and Cucumber), continuous integration, and agile methodologies. The community has also been a leader in promoting diversity and inclusion in tech, with initiatives like RailsBridge providing free workshops to underrepresented groups. Matz has remained actively involved in Ruby's development, guided by his philosophy that 'Ruby is designed to make programmers happy' and the principle of least surprise. The language continues to evolve with annual releases, balancing innovation with stability and backward compatibility. While Ruby faced competition from newer languages like Node.js and Go, and some companies have moved away from Rails for various reasons, Ruby remains a vital and beloved language with a strong community, mature ecosystem, and continued relevance in web development, DevOps tooling, and automation. The language's influence extends far beyond its direct usage, having inspired features in other languages and shaped how many developers think about API design, developer experience, and the joy of programming.
- 1993–1995
Matz wants a language he enjoys
Yukihiro Matsumoto sets out to build a scripting language more object-oriented than Perl and more practical than Smalltalk. His stated priority is the programmer's happiness rather than the machine's efficiency — an unusual goal that shows everywhere in the design.
- 2000
Ruby reaches the English-speaking world
*Programming Ruby* — the Pickaxe book — is published, and the language finally has documentation outside Japanese.
- 2004
Rails changes web development
David Heinemeier Hansson extracts Ruby on Rails from Basecamp. Convention over configuration, scaffolding, migrations and MVC-by-default make it dramatically faster to build a database-backed application, and the ideas spread to every other ecosystem.
- 2007–2012
The startup years
Twitter, GitHub, Shopify, Airbnb and Groupon are built on Rails. 'Ruby developer' becomes one of the most sought-after roles in the industry.
- 2013
Bundler and the gem ecosystem mature
Deterministic dependency resolution with `Gemfile.lock` solves the reproducibility problem, and RubyGems becomes one of the best-organised package ecosystems anywhere.
- 2020
Ruby 3.0 — the 3x3 goal
A target of three times the performance of Ruby 2.0, plus Ractors for parallelism, fibers for lightweight concurrency, and RBS for optional type signatures.
- 2022–2025
YJIT and steady gains
Shopify's YJIT, written in Rust, delivers substantial real-world speed-ups on Rails workloads. Rails 7 and 8 lean into Hotwire, importmaps and 'no build step' front ends.
What it is good at
The reasons teams pick it, stated concretely.
Genuinely pleasant to write
Blocks, expressive method names ending in `?` and `!`, and syntax that reads close to English. Ruby code is often the closest thing in software to a description of what it does — this is not a small thing on a codebase you live with for years.
Rails is still the fastest way to build a web application
Two decades of accumulated conventions mean the routing, ORM, migrations, background jobs, mailers, caching and testing are all decided for you and all work together. A small team can ship what would take much longer elsewhere.
Everything is an object, consistently
Integers, `nil` and classes themselves all respond to methods. There are no primitives with special rules, which makes the mental model unusually uniform.
Metaprogramming that libraries use well
`method_missing`, `define_method` and open classes let libraries create APIs that feel built into the language. ActiveRecord's dynamic finders and RSpec's readable syntax both come from here.
A culture of testing
The Ruby community adopted automated testing earlier and more thoroughly than most. RSpec, Minitest, factories and fixtures are standard practice rather than a discipline you have to argue for.
Trade-offs
Every language costs you something. Knowing what, before you commit, is the whole point.
Slower than compiled and JIT-heavy alternatives
Even with YJIT, CPU-bound Ruby is well behind Go, Java or Rust. For typical web applications, database time dominates and it rarely matters — but it does set a ceiling.
Memory-hungry per process
The traditional multi-process deployment model means each worker carries a full copy of the application. Hosting a Rails app costs more RAM than the Go or PHP equivalent.
The GVL limits real parallelism
Like CPython, MRI holds a global lock so threads cannot run Ruby code simultaneously. Ractors are the answer and are still marked experimental; in practice teams scale with processes.
Metaprogramming cuts both ways
Methods that do not exist in the source, monkey patches applied at load time, and behaviour assembled at runtime make some Ruby codebases genuinely hard to navigate. `grep` does not always find the definition.
Rails is a strong opinion
Follow the conventions and it is remarkable. Need something structured differently and you are working against a large, opinionated framework. 'Magic' is a fair description, and its cost lands on new team members.
Code examples
Not syntax tours — the idioms that make code read like the language rather than a translation of another one.
orders = [
{ region: 'EU', total: 120, status: :paid },
{ region: 'US', total: 340, status: :pending },
{ region: 'EU', total: 80, status: :paid },
]
revenue = orders
.select { |order| order[:status] == :paid }
.sum { |order| order[:total] }
by_region = orders.group_by { |order| order[:region] }
.transform_values { |list| list.sum { |o| o[:total] } }
puts revenue # 200
puts by_region # {"EU"=>200, "US"=>340}class Invoice
attr_reader :id, :amount
def initialize(id:, amount:)
raise ArgumentError, 'amount must be positive' unless amount.positive?
@id = id
@amount = amount
end
def large? # `?` by convention means it returns a boolean
amount > 1_000
end
def to_s = "#{id}: #{format('%.2f', amount)}"
end
invoice = Invoice.new(id: 'INV-1', amount: 1_500)
puts invoice # INV-1: 1500.00
puts invoice.large? # trueclass Book < ApplicationRecord
belongs_to :author
has_many :reviews, dependent: :destroy
validates :title, presence: true, length: { maximum: 200 }
validates :isbn, uniqueness: true, allow_nil: true
scope :recent, -> { where(published_at: 1.year.ago..) }
scope :highly_rated, -> { joins(:reviews).group(:id).having('AVG(reviews.rating) > 4') }
def average_rating = reviews.average(:rating)&.round(1)
end
# Composable, and lazily executed — one SQL query at the end.
Book.recent.highly_rated.includes(:author).limit(10)module Auditable
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def audited_fields(*fields)
@audited_fields = fields
end
def audited = @audited_fields || []
end
def audit_trail
self.class.audited.map { |field| "#{field}=#{public_send(field)}" }.join(' ')
end
end
class Order
include Auditable
audited_fields :id, :total
attr_reader :id, :total
def initialize(id, total) = (@id, @total = id, total)
end
puts Order.new('A-1', 99).audit_trail # id=A-1 total=99Common pitfalls
The mistakes that cost everyone an afternoon at least once.
N+1 queries in Rails
Looping over records and touching an association issues one query per row. Use `includes` or `preload`, and run the Bullet gem in development to catch them automatically.
Monkey patching core classes
Reopening `String` or `Hash` to add a method affects every gem in the process and produces conflicts nobody can trace. Use a refinement, or just a module function.
Confusing `nil` and `false` with everything else
In Ruby only `nil` and `false` are falsy — `0` and `""` are both truthy, unlike most other dynamic languages. This catches people arriving from JavaScript or Python.
Mutating a string or array you were handed
Bang methods such as `gsub!` and `sort!` modify in place, so a caller elsewhere sees the change. Prefer the non-bang versions unless mutation is the point.
Fat models and fatter controllers
Rails makes it easy to keep adding to a model until it is two thousand lines. Extract service objects, form objects and query objects before it gets there.
Symbols and strings as different hash keys
`{ name: 'a' }["name"]` returns nil. Rails' `HashWithIndifferentAccess` hides this in some places and not others, which makes it more confusing, not less.
In production
Where it is running at scale, and what it is doing there.
GitHub
Web application backend built with Ruby on Rails.
Shopify
E-commerce platform and merchant tools.
Basecamp
Project management and team collaboration tools.
Airbnb
Backend services and web application development.
Learning path
A realistic order to learn things in, with something to build at each step.
- 1
Week 1
The language and its feel
Objects and methods, strings and symbols, arrays and hashes, blocks, and control flow. Use `irb` constantly — Ruby rewards experimentation.
Build this: Write a script that parses a log file and reports the most frequent errors.
- 2
Weeks 2–3
Objects, modules and Enumerable
Classes, inheritance, modules and mixins, exceptions, and the `Enumerable` methods in depth. Learning `each_with_object`, `group_by`, `partition` and `reduce` well changes how you write everything else.
Build this: Model a small domain with classes and mixins, and write Minitest or RSpec tests for it.
- 3
Weeks 4–5
Tooling and gems
Bundler and `Gemfile.lock`, writing a gem, RuboCop, and debugging with `debug` or Pry. Understand how `require` and load paths work.
Build this: Package your script as a gem with a command-line executable and tests.
- 4
Months 2–4
Rails
MVC, routing, ActiveRecord and migrations, validations, ActionMailer, background jobs with Solid Queue or Sidekiq, and Hotwire for interactivity without a JavaScript framework.
Build this: Build and deploy a complete application with authentication, background jobs and system tests.
- 5
Ongoing
Depth and performance
Metaprogramming and when to avoid it, N+1 detection with Bullet, query and memory profiling, YJIT, and concurrency with fibers or Ractors.
Build this: Profile a slow Rails endpoint and cut its response time in half, starting with the queries.
Ecosystem and tooling
The tools you will end up installing whichever project you join.
| Tool | Category | What it does |
|---|---|---|
| Ruby on Rails | Framework | The full-stack web framework that made Ruby popular and still defines its ecosystem |
| Bundler + RubyGems | Packaging | Dependency resolution and packaging, with a lockfile for reproducible installs |
| RSpec / Minitest | Testing | Testing — RSpec for expressive specs, Minitest for a fast, minimal default |
| Sidekiq / Solid Queue | Jobs | Background job processing; Solid Queue ships with recent Rails and needs no Redis |
| RuboCop | Code quality | Linting and formatting against a widely adopted community style guide |
| Hotwire (Turbo + Stimulus) | Front end | Server-rendered interactivity, the Rails answer to single-page applications |
| Sorbet / RBS | Types | Optional static typing for large codebases |
| rbenv / asdf | Tooling | Ruby version management per project |
Ruby libraries
10 catalogued, each with installation, worked examples and best practices.
Ruby on Rails
Rails is a full-stack web framework covering routing, ORM, migrations, background jobs, mailers, caching and testing, built on convention over configuration.
Web & HTTPRSpec
RSpec is Ruby's behaviour-driven testing framework, with nested example groups, expressive matchers and built-in test doubles.
TestingSidekiq
Sidekiq is a high-performance background job processor for Ruby, using threads and Redis to run many jobs per process.
Messaging & StreamingRuboCop
RuboCop is a Ruby static code analyser and formatter, enforcing the community style guide with hundreds of configurable cops and autocorrection.
TestingSinatra
Sinatra is a minimal Ruby web framework — routes are blocks, there is no imposed structure, and the whole application can be one file.
Web & HTTPPuma
Puma is a concurrent HTTP server for Ruby, using a thread pool and optional worker processes, and is the default server for Rails.
Web & HTTP
Frequently asked
Is Ruby still relevant, or did it peak with Rails?
Its share of new startups is smaller than in 2010, but Shopify, GitHub, Stripe's early stack and a great many profitable businesses run on it at scale. Rails 7 and 8 have been genuinely well received, and YJIT delivered real performance gains. It is a mature, productive choice rather than a fashionable one.
Should I learn Ruby or go straight to Rails?
Spend two or three weeks on Ruby first. Rails leans heavily on blocks, modules and metaprogramming, and without those fundamentals the framework feels like unexplainable magic — which is exactly the complaint people who skipped this step tend to have.
Is Ruby too slow for production?
For typical web applications, no — response time is usually dominated by database queries and external calls, not by the interpreter. YJIT has improved things substantially. For CPU-bound work such as data processing or numerical computation, choose something else or push that part into a native extension.
Rails or a JavaScript framework for a new product?
Rails if a small team needs to ship a database-backed application quickly and the interface is mostly server-rendered — Hotwire covers a surprising amount of interactivity without a separate front end. A JavaScript stack if the product is genuinely application-like in the browser, or if you want one language across the whole system.
What is the deal with symbols?
A symbol such as `:name` is an immutable, interned identifier — the same symbol is the same object every time, so comparison is fast and no garbage accumulates. Use symbols for hash keys and identifiers, strings for text you will manipulate or display.
Do I need static typing in Ruby?
Most Ruby codebases run without it and rely on a strong test suite instead, which is a coherent position given the community's testing culture. For very large or long-lived codebases, Sorbet and RBS add real safety — Shopify and Stripe both invested heavily in this. For a small application, tests are usually the better use of your time.




