Pattern Matching: case/in Is case/when on Steroids
Ruby 3.0 introduced structural pattern matching withcase/in. Think of it as case/when that can reach inside your data, pull out specific values, and bind them to variables in one shot. If you've ever written five lines of Perl to unpack a nested hash ref, pattern matching does it in one expression.
Part 1: Basic Syntax
The key difference fromcase response in { status: 200, body: } # destructure hash, bind 'body' variable process(body) in { status: 404 } puts "not found" in { status: s } if s >= 500 # guard clause with variable binding puts "server error: #{s}" end
case/when: pattern matching uses in instead of when, and it destructures the data, binding variables automatically.
Part 2: Array Pattern Matching
case data in [Integer => first, *rest] # first must be Integer, rest is everything else puts "starts with number #{first}" in [String => name, Integer => age] puts "#{name} is #{age}" in [] # empty array puts "nothing here" end
Part 3: Hash Destructuring
# Pull specific keys out of a hash case config in { host: String => h, port: Integer => p } connect(h, p) in { host: String => h } connect(h, 5432) # default port end
Part 4: One-liner Destructure with =>
One line. Reaches into a nested hash, pulls out the name and email from the first element of an array, and binds them to local variables. Try doing that in Perl without losing your mind.# Pin a pattern match to a variable data = { users: [{ name: "Alice", email: "a@b.com" }, { name: "Bob" }] } data => { users: [{ name:, email: }, *rest] } puts "First user: #{name} <#{email}>" # name => "Alice", email => "a@b.com"
Part 5: Find Pattern (Searching Arrays)
The# Find an element matching a pattern inside an array case users in [*, { name: "Alice", role: } , *] puts "Alice's role: #{role}" end
[*, pattern, *] syntax searches through the array for any element matching the middle pattern. It's grep for structured data.
Part 6: Practical Ops Example
Parsing a JSON API response:require 'json' response = JSON.parse(api_result, symbolize_names: true) case response in { status: "ok", data: { servers: [{ hostname:, ip: }, *] } } puts "Primary server: #{hostname} (#{ip})" in { status: "error", message: } STDERR.puts "API error: #{message}" in { status: } STDERR.puts "Unknown status: #{status}" end
Part 7: Guard Clauses
case log_entry in { level: "ERROR", timestamp: t } if t > Time.now - 3600 puts "Recent error!" in { level: "ERROR" } puts "Old error, probably fine" end
Part 8: The in Operator (Standalone Check)
# Check if data matches a pattern (returns true/false) if config in { database: { host: String } } puts "Config has a database host string" end
Part 9: Perl Comparison
Perl has no direct equivalent. The closest would be manually unpacking hash refs and array refs with dereferencing. Ruby's pattern matching handles nested structures in a single expression that would take 5-10 lines of Perl. This is one area where Ruby genuinely leapfrogs Perl in expressiveness.Created By: Wildcard Wizard. Copyright 2026