Ruby Version History

Evolution of Ruby programming language

📜 Ruby's Journey

Ruby was created by Yukihiro Matsumoto in 1995. Over the years, it has evolved with new features, performance improvements, and modern programming capabilities. Understanding Ruby's history helps you appreciate its design philosophy and current features.


# Check your Ruby version
puts RUBY_VERSION
puts "Ruby #{RUBY_VERSION}"
                                    

Output:

3.2.0
Ruby 3.2.0

Major Ruby Eras

🌱

Ruby 1.x (1995-2003)

The foundation years

Basic OOP features
Blocks and iterators
🚀

Ruby 2.x (2013-2020)

Performance and refinement

Keyword arguments
Refinements, symbols
âš¡

Ruby 3.x (2020-Present)

Modern Ruby era

3x faster performance
Pattern matching, fibers
🔮

Future Ruby

Continuous evolution

Better concurrency
Type checking support

🔹 Ruby 1.x Era (1995-2003)

Ruby 1.x established the language's core philosophy of programmer happiness and productivity. These early versions introduced object-oriented programming, blocks, and the elegant syntax that made Ruby unique. This era laid the foundation for Ruby's future success.

# Ruby 1.0 (1996) - First stable release
# Basic object-oriented features
class Person
  def initialize(name)
    @name = name
  end
  
  def greet
    puts "Hello, I'm #{@name}"
  end
end

person = Person.new("Matz")
person.greet

# Ruby 1.6 (2000) - Blocks and iterators
[1, 2, 3].each do |num|
  puts num * 2
end

# Ruby 1.8 (2003) - Widely adopted version
# String interpolation
name = "Ruby"
puts "Welcome to #{name}!"

Output:

Hello, I'm Matz
2
4
6
Welcome to Ruby!

🔹 Ruby 2.0 (2013) - Major Milestone

Ruby 2.0 introduced keyword arguments, making method calls more readable and flexible. This version also added refinements for safer monkey patching and improved symbol handling. It marked Ruby's maturity as a production-ready language.

# Keyword arguments
def create_user(name:, age:, city: "Unknown")
  puts "Name: #{name}, Age: #{age}, City: #{city}"
end

create_user(name: "Alice", age: 25)
create_user(name: "Bob", age: 30, city: "NYC")

# Symbol to proc
numbers = [1, 2, 3, 4, 5]
puts numbers.map(&:to_s).inspect

# Lazy enumerators
range = (1..Float::INFINITY).lazy
result = range.select { |n| n % 3 == 0 }.first(5)
puts result.inspect

# Module prepend
module Greeting
  def hello
    "Hi! " + super
  end
end

class Person
  def hello
    "I'm a person"
  end
end

Person.prepend(Greeting)
puts Person.new.hello

Output:

Name: Alice, Age: 25, City: Unknown
Name: Bob, Age: 30, City: NYC
["1", "2", "3", "4", "5"]
[3, 6, 9, 12, 15]
Hi! I'm a person

🔹 Ruby 2.3-2.7 (2015-2019) - Refinements

These versions focused on performance improvements and developer experience. Ruby 2.3 introduced the safe navigation operator, 2.4 added hash improvements, and 2.7 prepared for Ruby 3 with pattern matching and numbered parameters.

# Ruby 2.3 - Safe navigation operator
user = nil
puts user&.name  # Returns nil instead of error

# Ruby 2.4 - Hash improvements
hash = { a: 1, b: 2, c: 3 }
new_hash = hash.transform_values { |v| v * 2 }
puts new_hash.inspect

# Ruby 2.5 - rescue in blocks
result = [1, 2, 3].map do |n|
  10 / n
rescue ZeroDivisionError
  0
end
puts result.inspect

# Ruby 2.6 - Endless range
numbers = [1, 2, 3, 4, 5]
puts numbers[2..].inspect

# Ruby 2.7 - Numbered parameters
squares = [1, 2, 3].map { _1 ** 2 }
puts squares.inspect

# Ruby 2.7 - Pattern matching (experimental)
case [1, 2, 3]
in [a, b, c]
  puts "Matched: #{a}, #{b}, #{c}"
end

Output:

nil
{:a=>2, :b=>4, :c=>6}
[10, 5, 3]
[3, 4, 5]
[1, 4, 9]
Matched: 1, 2, 3

🔹 Ruby 3.0 (2020) - Performance Revolution

Ruby 3.0 achieved the goal of being 3x faster than Ruby 2.0. It introduced major features like pattern matching, type definitions with RBS, and improved concurrency. This version represents modern Ruby's commitment to performance and developer productivity.

# Pattern matching (stable)
def check_value(value)
  case value
  in Integer => n if n > 0
    "Positive: #{n}"
  in Integer => n if n < 0
    "Negative: #{n}"
  in 0
    "Zero"
  in String => s
    "String: #{s}"
  else
    "Unknown"
  end
end

puts check_value(42)
puts check_value(-5)
puts check_value("hello")

# Rightward assignment
42 => x
puts "Value: #{x}"

# One-line pattern matching
[1, 2, 3] => [a, b, c]
puts "a=#{a}, b=#{b}, c=#{c}"

# Find pattern
case [1, 2, 3, 4, 5]
in [*, 3, *]
  puts "Found 3 in array"
end

# Endless method definition
def square(x) = x * x
puts square(5)

Output:

Positive: 42
Negative: -5
String: hello
Value: 42
a=1, b=2, c=3
Found 3 in array
25

🔹 Ruby 3.1-3.2 (2021-2023) - Modern Features

Recent Ruby versions continue improving performance and adding modern features. Ruby 3.1 introduced hash shorthand syntax, 3.2 added WASI support and improved pattern matching. These versions focus on making Ruby more efficient and developer-friendly.

# Ruby 3.1 - Hash value omission
name = "Alice"
age = 25
user = { name:, age: }
puts user.inspect

# Ruby 3.1 - Pin operator in pattern matching
expected = 42
case [1, 42, 3]
in [_, ^expected, _]
  puts "Found expected value!"
end

# Ruby 3.2 - Set operations
require 'set'
set1 = Set[1, 2, 3]
set2 = Set[2, 3, 4]
puts (set1 & set2).inspect
puts (set1 | set2).inspect

# Ruby 3.2 - Data class
Person = Data.define(:name, :age)
person = Person.new(name: "Bob", age: 30)
puts person.name
puts person.age

# Anonymous block parameter
def process(&)
  yield
end

process { puts "Block executed!" }

Output:

{:name=>"Alice", :age=>25}
Found expected value!
#
#
Bob
30
Block executed!

🔹 Checking Ruby Version

It's important to know which Ruby version you're using, as features vary between versions. Ruby provides several constants and methods to check version information, helping you write compatible code and debug version-specific issues.

# Version constants
puts "Ruby Version: #{RUBY_VERSION}"
puts "Ruby Patchlevel: #{RUBY_PATCHLEVEL}"
puts "Ruby Platform: #{RUBY_PLATFORM}"
puts "Ruby Release Date: #{RUBY_RELEASE_DATE}"

# Full version description
puts RUBY_DESCRIPTION

# Version comparison
if RUBY_VERSION >= "3.0"
  puts "Using Ruby 3 or later"
else
  puts "Using older Ruby version"
end

# Feature checking
if defined?(Data)
  puts "Data class is available (Ruby 3.2+)"
end

# Engine information
puts "Engine: #{RUBY_ENGINE}"
puts "Engine Version: #{RUBY_ENGINE_VERSION}"

Output:

Ruby Version: 3.2.0
Ruby Patchlevel: 0
Ruby Platform: x86_64-linux
Ruby Release Date: 2022-12-25
ruby 3.2.0 (2022-12-25) [x86_64-linux]
Using Ruby 3 or later
Data class is available (Ruby 3.2+)
Engine: ruby
Engine Version: 3.2.0

🧠 Test Your Knowledge

Which Ruby version introduced pattern matching as a stable feature?