File Coverage

blib/lib/Data/Hash/Diff/Smart.pm
Criterion Covered Total %
statement 30 30 100.0
branch n/a
condition n/a
subroutine 9 9 100.0
pod 5 5 100.0
total 44 44 100.0


line stmt bran cond sub pod time code
1             package Data::Hash::Diff::Smart;
2              
3 10     10   1363379 use strict;
  10         21  
  10         473  
4 10     10   50 use warnings;
  10         52  
  10         677  
5              
6 10     10   83 use Exporter 'import';
  10         17  
  10         328  
7 10     10   5709 use Data::Hash::Diff::Smart::Engine ();
  10         30  
  10         4298  
8              
9             our @EXPORT_OK = qw(
10             diff
11             diff_text
12             diff_json
13             diff_yaml
14             diff_test2
15             );
16              
17             our $VERSION = '0.01';
18              
19             =pod
20              
21             =head1 NAME
22              
23             Data::Hash::Diff::Smart - Smart structural diff for Perl data structures
24              
25             =head1 SYNOPSIS
26              
27             use Data::Hash::Diff::Smart qw(diff diff_text diff_json diff_yaml diff_test2);
28              
29             my $changes = diff($old, $new);
30              
31             print diff_text($old, $new);
32              
33             my $json = diff_json($old, $new);
34              
35             my $yaml = diff_yaml($old, $new);
36              
37             diag diff_test2($old, $new);
38              
39             =head1 DESCRIPTION
40              
41             C provides a modern, recursive, configurable diff
42             engine for Perl data structures. It understands nested hashes, arrays,
43             scalars, objects, and supports ignore rules, custom comparators, and
44             multiple array diffing strategies.
45              
46             The diff engine produces a stable, structured list of change operations,
47             which can be rendered as text, JSON, YAML, or Test2 diagnostics.
48              
49             =head1 FUNCTIONS
50              
51             =head2 diff($old, $new, %opts)
52              
53             Compute a structural diff between two Perl data structures.
54              
55             Returns an arrayref of change operations:
56              
57             [
58             { op => 'change', path => '/user/name', from => 'Nigel', to => 'N. Horne' },
59             { op => 'add', path => '/tags/2', value => 'admin' },
60             { op => 'remove', path => '/debug', from => 1 },
61             ]
62              
63             =head3 Options
64              
65             =over 4
66              
67             =item * ignore => [ '/path', qr{^/debug}, '/foo/*/bar' ]
68              
69             Ignore specific paths. Supports exact paths, regexes, and wildcard
70             segments.
71              
72             =item * compare => { '/price' => sub { abs($_[0] - $_[1]) < 0.01 } }
73              
74             Custom comparator callbacks for specific paths.
75              
76             =item * array_mode => 'index' | 'lcs' | 'unordered'
77              
78             Choose how arrays are diffed:
79              
80             =over 4
81              
82             =item * index - compare by index (default)
83              
84             =item * lcs - minimal diff using Longest Common Subsequence
85              
86             =item * unordered - treat arrays as multisets (order ignored)
87              
88             =back
89              
90             =back
91              
92             =head2 diff_text($old, $new, %opts)
93              
94             Render the diff as a human-readable text format.
95              
96             =head2 diff_json($old, $new, %opts)
97              
98             Render the diff as JSON using C.
99              
100             =head2 diff_yaml($old, $new, %opts)
101              
102             Render the diff as YAML using C.
103              
104             =head2 diff_test2($old, $new, %opts)
105              
106             Render the diff as Test2 diagnostics suitable for C.
107              
108             =head1 INTERNALS
109              
110             The diff engine lives in L.
111              
112             =cut
113              
114             # Core diff
115             sub diff {
116 26     26 1 1096751 my ($old, $new, %opts) = @_;
117 26         128 return Data::Hash::Diff::Smart::Engine::diff($old, $new, %opts);
118             }
119              
120             # Text renderer (lazy-loaded)
121             sub diff_text {
122 4     4 1 245243 my ($old, $new, %opts) = @_;
123 4         883 require Data::Hash::Diff::Smart::Renderer::Text;
124 4         18 my $changes = diff($old, $new, %opts);
125 4         15 return Data::Hash::Diff::Smart::Renderer::Text::render($changes);
126             }
127              
128             # JSON renderer (lazy-loaded)
129             sub diff_json {
130 4     4 1 224276 my ($old, $new, %opts) = @_;
131 4         809 require Data::Hash::Diff::Smart::Renderer::JSON;
132 4         20 my $changes = diff($old, $new, %opts);
133 4         10 return Data::Hash::Diff::Smart::Renderer::JSON::render($changes);
134             }
135              
136             # YAML renderer (lazy-loaded)
137             sub diff_yaml {
138 4     4 1 248140 my ($old, $new, %opts) = @_;
139 4         922 require Data::Hash::Diff::Smart::Renderer::YAML;
140 4         20 my $changes = diff($old, $new, %opts);
141 4         13 return Data::Hash::Diff::Smart::Renderer::YAML::render($changes);
142             }
143              
144             sub diff_test2 {
145 4     4 1 209953 my ($old, $new, %opts) = @_;
146 4         866 require Data::Hash::Diff::Smart::Renderer::Test2;
147 4         20 my $changes = diff($old, $new, %opts);
148 4         17 return Data::Hash::Diff::Smart::Renderer::Test2::render($changes);
149             }
150              
151             1;
152              
153             =head1 AUTHOR
154              
155             Nigel Horne, C<< >>
156              
157             =head1 REPOSITORY
158              
159             L
160              
161             =head1 SUPPORT
162              
163             This module is provided as-is without any warranty.
164              
165             Please report any bugs or feature requests to C,
166             or through the web interface at
167             L.
168             I will be notified, and then you'll
169             automatically be notified of progress on your bug as I make changes.
170              
171             You can find documentation for this module with the perldoc command.
172              
173             perldoc Data::Hash::Diff::Smart
174              
175             You can also look for information at:
176              
177             =over 4
178              
179             =item * MetaCPAN
180              
181             L
182              
183             =item * RT: CPAN's request tracker
184              
185             L
186              
187             =item * CPAN Testers' Matrix
188              
189             L
190              
191             =item * CPAN Testers Dependencies
192              
193             L
194              
195             =back
196              
197             =head1 LICENCE AND COPYRIGHT
198              
199             Copyright 2026 Nigel Horne.
200              
201             Usage is subject to licence terms.
202              
203             The licence terms of this software are as follows:
204              
205             =over 4
206              
207             =item * Personal single user, single computer use: GPL2
208              
209             =item * All other users (including Commercial, Charity, Educational, Government)
210             must apply in writing for a licence for use from Nigel Horne at the
211             above e-mail.
212              
213             =back
214              
215             =cut
216              
217             1;