Skip to content

Instantly share code, notes, and snippets.

@jjb
Created April 18, 2024 00:40
Show Gist options
  • Save jjb/a633b1ee9d0bc49f6f0372e038274ae8 to your computer and use it in GitHub Desktop.
Save jjb/a633b1ee9d0bc49f6f0372e038274ae8 to your computer and use it in GitHub Desktop.
Hacking ruby patterns to be first-class objects that can be passed around
# need to "pin" the variable, but this only works with the lambda because
# pattern matching falls back to case matchint (=== on any object in ruby,
# which is NOT "identical object" as in JS)
def matches1(pat,x)
case x
in ^pat
puts true
else
puts false
end
end
# a "more honest" implementation, same behavior
def matches2(pat,x)
case x
when pat
puts true
else
puts false
end
end
# these don't work
matches1({a: Integer}, {a: 5, b: 6})
matches1({a: Integer}, {a: "hello", b: 6})
# all of the below works
my_pattern = -> { _1 in {a: Integer} }
# more verbose
# my_pattern = ->(value) { value in {a: Integer} }
# more verbose
# my_pattern = lambda do |value|
# value in {a: Integer}
# end
matches1(my_pattern, {a: 5, b: 6})
matches1(my_pattern, {a: "hello", b: 6})
matches2(my_pattern, {a: 5, b: 6})
matches2(my_pattern, {a: "hello", b: 6})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment