Subject: | match::smart::match(ARRAY,ARRAY) short circuiting |
Consider the following smart match comparisons of two arrays of strings. My expectation is that they will be considered non-matching since the second values in each are not equal. The built-in '~~' agrees with my expectations:
Show quoted text
> perl -E 'my $c = [ 1,2 ]; my $d = [ 1,3 ]; say $c ~~ $d ? q(match) : q(no-match)'
no-match
But the module match() subroutine considers them matching even though the second element differs:
Show quoted text> perl -Mlocal::lib -Mmatch::smart=match -E 'my $c = [ 1,2 ]; my $d = [ 1,3 ]; say match( $c, $d ) ? q(match) : q(no-match)'
From reviewing the match::smart::match() code this appears to relate to how $seen tracks the refaddr() of $b. After match() recurses and starts iterating over the array values, when $b contains '2', the refaddr() is 'undef', and it increments $seen{undef}.
On the second iteration, when $b contains '3', refaddr() is again undef, which already exists in $seen, triggering a short-circuit that returns true since refaddr() of both values is undef.
return refaddr($a)==refaddr($b) if $seen->{refaddr($b)}++;