Search code examples
rubypattern-matching

Pattern matching in ruby with hashes


When i was learning about pattern matching in ruby, i came across this issue

hash = { name: 1, age: 21, location: "NYC" }
case hash
in {name: String => x, age:y, location:z}
    puts "Name: #{x}, Age: #{y}, Location: #{z}"
in {name: x, age:y}
    puts "Name: #{x}, Age: #{y}"
else
    puts "Invalid pattern"
end 

In the above code, i expected Invalid pattern to be printed on the screen(since the name keyword value is an integer), but when i ran in in replit, the value printed on the console was Name: 1, Age: 21

How does this happen? For the second in condition, the hash must only have name and age, but in the hash provided, it has name, age and location


Solution

  • Hash patterns by default ignore extra keys in the matched value, except for empty hash pattern which only matches the empty hash.

    If you want to exactly match a non-empty Hash, you can add **nil to the pattern:

    Change:

    in {name: x, age: y}
    

    to:

    in {name: x, age: y, **nil}
    

    and your code will print "Invalid pattern".

    It's documented here.