my ($pre, $post) is short for (my $pre, my $post).
A list-like expression on the LHS of = (such as my ($pre, $post)) causes the list assignment (aassign) operator to be used instead of a scalar assignment (sassign) operator.
The list assignment operator evaluates its RHS operand in list context.
In list context, m// (no "g") returns
() if the match failed,
the captures if the match succeeded and the pattern contains captures, or
1 (one) if the match succeeded and the pattern contains no captures.
The list assignment operator returns the number of elements returned by its RHS operand.
The if condition will be false when the match fails because the list assignment operator returned 0 (zero) because the match operator returned zero elements.
The if condition will be true when the match succeeds because the list assignment operator returned 2 (two) because the match operator returned two captures.
And finally, each level of recursion of the function get its own pad, which means my ($pre, $post) creates new variables for each level of recursion, which means the they keep their value even through a recursive call.