File Coverage

blib/lib/Data/Walk/More.pm
Criterion Covered Total %
statement 63 75 84.0
branch 16 26 61.5
condition 5 10 50.0
subroutine 8 9 88.8
pod 2 2 100.0
total 94 122 77.0


line stmt bran cond sub pod time code
1             ## no critic: Modules::ProhibitAutomaticExportation
2              
3             package Data::Walk::More;
4              
5             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
6             our $DATE = '2020-04-15'; # DATE
7             our $DIST = 'Data-Walk-More'; # DIST
8             our $VERSION = '0.001'; # VERSION
9              
10 1     1   67245 use 5.010001;
  1         11  
11 1     1   7 use strict;
  1         1  
  1         31  
12 1     1   6 use warnings;
  1         2  
  1         24  
13 1     1   1737 use Log::ger;
  1         49  
  1         4  
14              
15 1     1   246 use Scalar::Util qw(blessed reftype refaddr);
  1         2  
  1         55  
16              
17 1     1   5 use Exporter qw(import);
  1         2  
  1         681  
18             our @EXPORT = qw(walk walkdepth);
19              
20             our %_seen_refaddrs;
21              
22             our $depth;
23             our @containers;
24             our $container;
25             our @indexes;
26             our $index;
27             our $prune;
28              
29             sub _walk {
30 50     50   78 my ($opts, $val) = @_;
31              
32 50         77 my $ref = ref $val;
33 50 100       84 if ($ref eq '') {
34 32         46 local $_ = $val; $opts->{wanted}->();
  32         70  
35 32         115 return;
36             }
37              
38 18         38 my $refaddr = refaddr($val);
39 18 50       48 if ($_seen_refaddrs{$refaddr}++) {
40 0 0       0 return unless $opts->{follow};
41             }
42              
43 18         25 my $class;
44 18 50       39 if (blessed $val) {
45 0         0 $class = $ref;
46 0         0 $ref = reftype($val);
47             }
48              
49             RECURSE_ARRAY_HASH: {
50 18 50 66     23 last unless $ref eq 'ARRAY' || $ref eq 'HASH';
  18         50  
51 18 50 33     39 last if !$opts->{recurseobjects} && defined $class;
52              
53 18 100       32 unless ($opts->{bydepth}) {
54 17         25 local $_ = $val; $opts->{wanted}->();
  17         33  
55             }
56              
57 18 50       90 if ($prune) {
58 0         0 $prune = 0;
59 0         0 return;
60             }
61              
62             {
63 18         22 local $depth = $depth + 1;
  18         27  
64 18         41 local @containers = (@containers, $val);
65 18         21 local $container = $containers[-1];
66 18         34 local @indexes = (@indexes, undef);
67 18         24 local $index;
68 18 100       33 if ($ref eq 'ARRAY') {
69 14         17 for my $i (0..$#{$val}) {
  14         33  
70 36         49 $indexes[-1] = $i;
71 36         40 $index = $i;
72 36         66 _walk($opts, $val->[$i]);
73             }
74             } else { # HASH
75 4 50       21 for my $k ($opts->{sortkeys} ? (sort keys %$val) : (keys %$val)) {
76 8         12 $indexes[-1] = $k;
77 8         12 $index = $k;
78 8         16 _walk($opts, $val->{$k});
79             }
80             }
81             }
82              
83 18 100       38 if ($opts->{bydepth}) {
84 1         3 local $_ = $val; $opts->{wanted}->();
  1         2  
85             }
86              
87 18         46 return;
88             } # RECURSE_ARRAY_HASH
89              
90 0         0 local $_ = $val; $opts->{wanted}->();
  0         0  
91 0         0 return;
92             }
93              
94             sub walk {
95 6 100   6 1 12255 my $opts = ref($_[0]) eq 'HASH' ? { %{shift()} } : { wanted=>shift() };
  2         8  
96 6   50     32 $opts->{recurseobjects} //= 1;
97 6   50     22 $opts->{sortkeys} //= 1;
98              
99 6         12 local %_seen_refaddrs;
100 6         12 for my $data (@_) {
101 6         8 local $depth = 0;
102 6         21 local $prune = 0;
103 6         11 _walk($opts, $data);
104             }
105             }
106              
107             sub walkdepth {
108 0 0   0 1   my $opts = ref($_[0]) eq 'HASH' ? { %{shift()} } : { wanted=>shift() };
  0            
109 0           $opts->{bydepth} = 1;
110 0           walk($opts, @_);
111             }
112              
113             1;
114             # ABSTRACT: Traverse Perl data structures, with more information during traversing
115              
116             __END__