im lazy. straight from copilot 
Pattern Matching with String Keys
By default, Ruby’s hash pattern matching expects symbol keys. That’s why
your example works when you load YAML with symbolize_names: true. If you
keep string keys, you need to explicitly match them:
ruby
y = YAML.safe_load(yaml_data) # no symbolize_names
y["cards_on_hand"].each do |a_card|
case a_card
in { "suite" => String => captured_suite, "value" => "king" }
puts "you have a king on your hand and its suite is #{captured_suite}"
else
puts "a card of no interest #{a_card.inspect}"
end
end
Notice the difference:
suite: → matches a symbol key
"suite" => → matches a string key
So:
Use symbolize_names: true if you want to work with symbols.
Or match with "key" => if you want to keep string keys.
Passing Patterns into Functions
Patterns in Ruby are objects (they’re part of the language syntax). You
can’t directly “store” a pattern as a variable, but you can wrap matching
logic in a method and use case ... in inside it.
Example:
ruby
def match_card(card, pattern)
case card
in pattern
yield $~ if block_given? # or just return true
else
nil
end
end
pattern = { suite: String => suite, value: "king" }
y[:cards_on_hand].each do |card|
match_card(card, pattern) do
puts "Captured suite: #{suite}"
end
end
Another approach is to use procs/lambdas for reusable matching logic:
ruby
king_pattern = ->(card) {
case card
in { suite: String => s, value: "king" }
s
else
nil
end
}
y[:cards_on_hand].each do |card|
if (suite = king_pattern.call(card))
puts "You have a king of #{suite}"
end
end
This way, you can pass around reusable matchers like any other object.
Key Takeaways
Use symbol: for symbol keys, "string" => for string keys.
Wrap patterns in methods or lambdas to pass them around.
Captures (=> var) work fine inside those reusable matchers.
···
On Tue, May 26, 2026 at 10:12 PM Marcus Poller via ruby-talk < ruby-talk@ml.ruby-lang.org> wrote:
Hi Rubyists,
is this the place to ask beginner questions?
I am confused about pattern matching. It only seems to work when the key
is of type symbol.
How would I apply pattern matching to string keys?
Example
require "yaml"
yaml_data="
cards_on_hand:
- suite: hearts
value: '9'
- suite: hearts
value: 'king'
- suite: diamonds
value: 'king'
"
y=YAML.safe_load(yaml_data, symbolize_names: true)
puts y.inspect
y[:cards_on_hand].each do |a_card|
case a_card
in { suite: String => captured_suite, value: 'king' }
puts "you have a king on your hand and its suite is #{captured_suite}"
else
puts "a card of no interest #{a_card.inspect}"
end
end
{cards_on_hand: [{suit: "hearts", value: "9"}, {suit: "hearts", value:
"king"}, {suit: "diamonds", value: "king"}]}
a card of no interest {suite: "hearts", value: "9"}
you have a king on your hand and its suite is hearts
you have a king on your hand and its suite is diamonds
Second question:
Since everything in Ruby is an object, how do I pass patterns into a
function? Even more specific, how do I handle capture when passing to a
function?
Cheers,
Marcus
______________________________________________
ruby-talk mailing list -- ruby-talk@ml.ruby-lang.org
To unsubscribe send an email to ruby-talk-leave@ml.ruby-lang.org
ruby-talk info --
https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-talk.ml.ruby-lang.org/