Ruby Pattern Matching

Sebastian Suttner
Sep 3, 2019 · 5 min read
Image for post
Image for post

Syntax

case expr
in pattern [if|unless condition]
...
in pattern [if|unless condition]
...
else
...
end
case [0, 1]
in [a, b] unless a == b
:match
end
#=> :match

Patterns

VALUE PATTERN

case 0
in 0
:match
end
#=> :match
case 0
in -1..1
:match
end
#=> :match
case 0
in 3..6
:no_match
end
#=> NoMatchingPatternError (0)
case 0
in Integer
:match
end
#=> :match
case 0
in String
:no_match
end
#=> NoMatchingPatternError (0)

VARIABLE PATTERN

case 0
in a
a
end
#=> 0
a = 0
case 1
in a
a
end
#=> 1
a = 0
case 1
in ^a # this translates to: `in 0`
:no_match
end
#=> NoMatchingPatternError
case [0, 1]
in [_, a]
a
end
#=> 1

ALTERNATIVE PATTERN

case 0
in 0 | 1 | 2
:match
end
#=> :match

AS PATTERN

case [0, 1]
in [0, a => b]
b
end
#=> 1

ARRAY PATTERN

case [0, 1, 2]
in [0, a, 3]
:no_match
end
#=> NoMatchingPatternError ([0, 1, 2])
case [0, 1, 2]
in [0, a, 2]
a
end
#=> 1
case [0, 1, 2]
in [0, *tail]
tail
end
#=> [1, 2]
case [0, 1, 2]
in Array(0, a, 2)
a
end
#=> 1
case [0, 1, 2]
in Object[0, a, 2]
a
end
#=> 1
case [0, 1, 2]
in 0, a, 2
a
end
#=> 1
class Struct
def deconstruct
to_a
end
end
Color = Struct.new(:r, :g, :b)color = Color[0, 10, 20]
color.deconstruct
#=> [0, 10, 20]
case color 
in Color[0, 0, 0]
:no_match
in Color[255, 0, 0]
:no_match
in Color[r, g, b]
"#{r}, #{g}, #{b}"
end
#=> "0, 10, 20"

HASH PATTERN

case {a: 0, b: 1, c: 2}
in {a: 0, b: b, c: 3}
:no_match
end
#=> NoMatchingPatternError ({:a=>0, :b=>1, :c=>2})
case {a: 0, b: 1, c: 2}
in {a: 0, b: b, c: 2}
b
end
#=> 1
case {a: 0, b: 1, c: 2}
in {a: 0, **rest}
rest
end
#=> {:b=>1, :c=>2}
case {a: 0, b: 1, c: 2}
in Hash(a: 0, b: b, c: 2)
b
end
#=> 1
case {a: 0, b: 1, c: 2}
in Object[a: 0, b: b, c: 2]
b
end
#=> 1
case {a: 0, b: 1, c: 2}
in {a:, b:, c:}
b
end
#=> 1
case {a: 0, b: 1, c: 2}
in a: 0, b: b, c: 2
b
end
#=> 1
case {a: 0, b: 1, c: 2}
in a:, b:, c:
b
end
#=> 1
case {a: 0, b: 1, c: 2}
in b:
b
end
#=> 1
class Date
def deconstruct_keys(keys)
{year: year, month: month, day: day}
end
end
class Date
VALID_KEYS = %i(year month day)
def deconstruct_keys(keys)
if keys
(VALID_KEYS & keys).each_with_object({}) do |k, h|
h[k] = send(k)
end
end
end
end
today = Date.today
today.deconstruct_keys([:year])
#=> {year: 2019}
class Date
VALID_KEYS = %i(year month day)
def deconstruct_keys(keys)
if keys
(VALID_KEYS & keys).each_with_object({}) do |k, h|
h[k] = send(k)
end
else
{year: year, month: month, day: day}
end
end
end
today = Date.today
today.deconstruct_keys(nil)
#=> {year: 2019, month: 9, day: 1}
case today
in year:
year
end
#=> 2019

Conclusion

Cedarcode

Adding value from day one.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store