Last active
February 1, 2024 16:14
-
-
Save RomanTurner/1ed15b5e8474a215901393c936027f0b to your computer and use it in GitHub Desktop.
Ruby Pattern Matching
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Response | |
attr_reader :status, :data | |
def initialize(status, data) | |
@status = status | |
@data = data | |
end | |
def deconstruct | |
by_status | |
end | |
def deconstruct_keys(_keys) | |
by_status | |
end | |
private | |
def by_status(ok: nil, error: nil, not_found: nil) | |
case @status | |
when 200 | |
ok || { ok: @data } | |
when 404 | |
not_found || { error: "File not found" } | |
else | |
error || {error: @data } | |
end | |
end | |
end | |
data = { one: "two", three: "four" } | |
case Response.new(200, data) | |
in ok: result | |
puts "Success: #{result}" | |
in error: reason | |
puts "Error: #{reason}" | |
end | |
#=> "Success: { one: "two", three: "four" }" | |
case Response.new(403, "Something went wrong") | |
in ok: result | |
puts "Success: #{result}" | |
in error: reason | |
puts "Error: #{reason}" | |
end | |
# => "Error: Something went wrong" | |
case Response.new(404) | |
in ok: result | |
puts "Success: #{result}" | |
in error: reason | |
puts "Error: #{reason}" | |
end | |
# => "Error: File not found" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Imagine that you get a custom class returned from an API | |
ApiCustomResponseClass = | |
Struct.new(:status, :body, :message, keyword_init: true) do | |
def success? | |
status == 200 | |
end | |
end | |
# It probably does not have #deconstruct or #deconstruct_keys so this Response class acts as a helpful wrapper. | |
class Response | |
attr_reader :status, :data | |
def initialize(res) | |
@status = res.status | |
@data = res.success? ? res.body : res.message | |
end | |
def deconstruct | |
by_status | |
end | |
def deconstruct_keys(_keys) | |
by_status | |
end | |
private | |
def by_status(ok: nil, error: nil, not_found: nil) | |
case @status | |
when 200 | |
{ ok: @data } | |
else | |
{ error: @data } | |
end | |
end | |
end | |
successful_response = | |
ApiCustomResponseClass.new( | |
{ status: 200, body: { one: "two", three: "four" } } | |
) | |
failed_response = | |
ApiCustomResponseClass.new({ status: 403, message: "Unauthorized" }) | |
not_found_response = | |
ApiCustomResponseClass.new({ status: 404, message: "File Not Found" }) | |
[successful_response, failed_response, not_found_response].each do |res| | |
case Response.new(res) | |
in ok: result | |
puts "Success: #{result}" | |
in error: reason | |
puts "Error: #{reason}" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment