From 19e79470e7b6e4e654520fce7bb02d09caeb8a5e Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Thu, 7 Jul 2011 09:08:23 -0500 Subject: fix circular data structures --- lib/smartmatch/engine/core.pm | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/smartmatch/engine/core.pm b/lib/smartmatch/engine/core.pm index e172b6c..cad2e5c 100644 --- a/lib/smartmatch/engine/core.pm +++ b/lib/smartmatch/engine/core.pm @@ -3,6 +3,7 @@ use strict; use warnings; use B; +use Hash::Util::FieldHash qw(idhash); use Scalar::Util qw(blessed looks_like_number reftype); use overload (); @@ -48,7 +49,7 @@ sub type { } sub match { - my ($a, $b) = @_; + my ($a, $b, $seen) = @_; if (type($b) eq 'undef') { return !defined($a); @@ -109,8 +110,15 @@ sub match { } elsif (type($a) eq 'Array') { return unless @$a == @$b; + if (!$seen) { + $seen = {}; + idhash %$seen; + } for my $i (0..$#$a) { - return unless match($a->[$i], $b->[$i]); + if (defined($b->[$i]) && $seen->{$b->[$i]}++) { + return $a->[$i] == $b->[$i]; + } + return unless match($a->[$i], $b->[$i], $seen); } return 1; } @@ -121,7 +129,16 @@ sub match { return grep !defined, @$b; } else { - return grep { match($a, $_) } @$b; + if (!$seen) { + $seen = {}; + idhash %$seen; + } + return grep { + if (defined($_) && $seen->{$_}++) { + return $a == $_; + } + match($a, $_, $seen) + } @$b; } } elsif (type($b) eq 'Regex') { -- cgit v1.2.3