In the Tip of the Weeklast week, we discussed how we could use variable pinning in pattern matching to compare a pattern to a local variable. Another use case for variable pinning in pattern matching is to compare a value within the same pattern. Let's say we want to make sure that both elements in an array are the same, but we don't care exactly what they are. We can use variable pinning again here. Let's take a look: case [1,1]
in [element,^element]
"elements are the same: #{element}"
else
"elements are different: #{element}"
end
=> elements are the same: 1
We assigned the first element to the variable element , and then used variable pinning (^element ) to compare the second element to the first element. We can also confirm that if the two elements in the array weren't the same, we'd fall into the else case, with element sitll set to be the first element of the array: case [1,"different"]
in [element,^element]
"elements are the same: #{element}"
else
"elements are different: #{element}"
end
=> "elements are different: 1"
The Ruby docs give an interesting and practical use case for variable pinning. In the case from their example, we have a nested data structure where we have the school that jane is in, and the ids corresponding to each type of school. We want to find the id that matches her specific schoool type: jane = {school: 'high', schools:[
{id: 1, level: 'middle'},
{id: 2, level: 'high'}]
}
case jane
# select the last school, level should match
in school:, schools: [*, {id:, level: ^school}]
"matched. school: #{id}"
else
"not matched"
end
#=> "matched. school: 2"
Neat! We assigned the variable school to the value with the key school , and then pinned school to ensure it matched the level. This led us to the id we sought for high school, 2 . Variable pinning in pattern matching can be very helpful in these cases, as it allows us to match to values within the pattern itself. |