Created
October 28, 2022 15:07
-
-
Save kddnewton/c4f7f1226e0831a025aa29def7d9a6d6 to your computer and use it in GitHub Desktop.
Pattern matching
This file contains 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
# This module is a light implementation of pattern matching that allows us to | |
# match against hashes and arrays as we would with the new pattern matching | |
# syntax. | |
module Pattern | |
class ArrayPattern | |
attr_reader :values | |
def initialize(values) | |
@values = values | |
end | |
def ===(other) | |
deconstructed = other.deconstruct | |
values.each_with_index.all? do |value, index| | |
value === deconstructed[index] | |
end | |
end | |
end | |
class HashPattern | |
attr_reader :values | |
def initialize(values) | |
@values = values | |
end | |
def ===(other) | |
deconstructed = other.deconstruct_keys(values.keys) | |
values.all? do |key, value| | |
value == :any ? deconstructed.key?(key) : value === deconstructed[key] | |
end | |
end | |
end | |
def self.[](value) | |
case value | |
when Array | |
ArrayPattern.new(value.map { |child| self[child] }) | |
when Hash | |
HashPattern.new(value.transform_values { |child| self[child] }) | |
else | |
value | |
end | |
end | |
end | |
require "json" | |
source = '{ "a": 1, "b": [2, 3], "c": "Hello, world!" }' | |
case JSON.parse(source, symbolize_names: true) | |
when Pattern[a: 1] # <-- match against individual values | |
puts "Matched value!" | |
when Pattern[b: [2, 3]] # <-- match against lists of values | |
puts "Matched list!" | |
when Pattern[a: Integer] # <-- match against classes | |
puts "Matched class!" | |
when Pattern[c: /Hello/] # <-- match against regular expressions | |
puts "Matched regular expression!" | |
when Pattern[a: :any] # <-- match against any value | |
puts "Matched wildcard!" | |
else | |
puts "No match!" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment