Skip to content

Conversation

@baweaver
Copy link

@baweaver baweaver commented Nov 9, 2025

Summary

Adds pattern matching support to URI::Generic via the deconstruct_keys method, enabling more expressive URI handling in Ruby 2.7+.

Motivation

Pattern matching provides a cleaner, more declarative way to work with URIs, especially when routing or filtering based on URI components.

Current approach:

uri = URI(request_url)
if uri.scheme == "https" && uri.host == "api.example.com" && uri.path.start_with?("/v2")
 handle_api_v2_request(uri)
end

With pattern matching:

case URI(request_url)
in scheme: "https", host: "api.example.com", path: /^\/v2/
 handle_api_v2_request
end

Implementation

Added deconstruct_keys method to URI::Generic that returns a hash with the following keys:

  • :scheme, :userinfo, :host, :port, :path, :query, :fragment
  • :params - Parsed query string as a hash with symbol keys (lazily computed only when requested)

The :params key is only computed when explicitly requested to avoid unnecessary parsing overhead.

Examples

Basic pattern matching:

uri = URI("https://example.com:8080/search?q=ruby")

case uri
in scheme: "https", host: "example.com"
 # matches
end

Matching with query params:

uri = URI("http://example.com/search?q=ruby&lang=en")

case uri
in scheme: "http", path: "/search", params: { q: "ruby" }
 # matches - params are parsed as { q: "ruby", lang: "en" }
end

Compatibility

Tests are wrapped with instance_eval and SyntaxError rescue to maintain compatibility with Ruby 2.5+, as pattern matching syntax was introduced in Ruby 2.7.

Testing

  • Added tests for deconstruct_keys with and without params
  • Added pattern matching tests for scheme/host matching
  • Added pattern matching tests with params hash
  • All existing tests pass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant