File Coverage

blib/lib/Data/Difference.pm
Criterion Covered Total %
statement 34 42 80.9
branch 29 44 65.9
condition n/a
subroutine 6 6 100.0
pod 0 1 0.0
total 69 93 74.1


line stmt bran cond sub pod time code
1             package Data::Difference;
2             {
3             $Data::Difference::VERSION = '0.112850';
4             }
5              
6 1     1   58526 use strict;
  1         2  
  1         35  
7 1     1   6 use warnings;
  1         1  
  1         68  
8 1     1   5 use base 'Exporter';
  1         5  
  1         1193  
9              
10             our @EXPORT_OK = qw(data_diff);
11              
12             sub data_diff {
13 5     5 0 15402 my ($a, $b) = @_;
14              
15 5 50       34 if (ref($a)) {
    100          
    100          
    100          
16 3 50       44 if (my $sub = __PACKAGE__->can("_diff_" . ref($a))) {
17 3         9 return $sub->($a, $b);
18             }
19             else {
20 0         0 return {path => [], a => $a, b => $b};
21             }
22             }
23             elsif (defined $a ? defined $b ? $a ne $b : 1 : 0) {
24 1         12 return {path => [], a => $a, b => $b};
25             }
26              
27 1         10 return;
28             }
29              
30             sub _diff_HASH {
31 1     1   5 my ($a, $b, @path) = @_;
32              
33 1 50       7 return {path => \@path, a => $a, b => $b} unless ref($a) eq ref($b);
34              
35 1         2 my @diff;
36             my %k;
37 1         9 @k{keys %$a, keys %$b} = ();
38 1         8 foreach my $k (sort keys %k) {
39 4 50       30 if (!exists $a->{$k}) {
    50          
    100          
    100          
    50          
    100          
40 1         4 push @diff, {path => [@path, $k], b => $b->{$k}};
41             }
42             elsif (!exists $b->{$k}) {
43 1         6 push @diff, {path => [@path, $k], a => $a->{$k}};
44             }
45             elsif (ref($a->{$k})) {
46 0 0       0 if (my $sub = __PACKAGE__->can("_diff_" . ref($a->{$k}))) {
47 0         0 push @diff, $sub->($a->{$k}, $b->{$k}, @path, $k);
48             }
49             else {
50 0         0 push @diff, {path => [@path, $k], a => $a->{$k}, b => $b->{$k}};
51             }
52             }
53             elsif (defined $a->{$k} ? defined $b->{$k} ? $b->{$k} ne $a->{$k} : 1 : 0) {
54 1         8 push @diff, {path => [@path, $k], a => $a->{$k}, b => $b->{$k}};
55             }
56             }
57              
58 1         9 return @diff;
59             }
60              
61             sub _diff_ARRAY {
62 2     2   5 my ($a, $b, @path) = @_;
63 2 50       10 return {path => \@path, a => $a, b => $b} unless ref($a) eq ref($b);
64              
65 2         3 my @diff;
66 2 100       8 my $n = $#$a > $#$b ? $#$a : $#$b;
67              
68 2         7 foreach my $i (0 .. $n) {
69 6 50       44 if ($i > $#$a) {
    50          
    100          
    100          
    50          
    50          
70 1         6 push @diff, {path => [@path, $i], b => $b->[$i]};
71             }
72             elsif ($i > $#$b) {
73 1         8 push @diff, {path => [@path, $i], a => $a->[$i]};
74             }
75             elsif (ref($a->[$i])) {
76 0 0       0 if (my $sub = __PACKAGE__->can("_diff_" . ref($a->[$i]))) {
77 0         0 push @diff, $sub->($a->[$i], $b->[$i], @path, $i);
78             }
79             else {
80 0         0 push @diff, {path => [@path, $i], a => $a->[$i], b => $b->[$i]};
81             }
82             }
83             elsif (defined $a->[$i] ? defined $b->[$i] ? $b->[$i] ne $a->[$i] : 1 : 0) {
84 0         0 push @diff, {path => [@path, $i], a => $a->[$i], b => $b->[$i]};
85             }
86             }
87              
88 2         17 return @diff;
89             }
90              
91             1;
92              
93             __END__