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 1     1   56791 use 5.010001;
  1         11  
6 1     1   4 use strict;
  1         1  
  1         17  
7 1     1   3 use warnings;
  1         1  
  1         29  
8 1     1   1546 use Log::ger;
  1         44  
  1         4  
9              
10 1     1   203 use Exporter qw(import);
  1         2  
  1         25  
11 1     1   5 use Scalar::Util qw(blessed reftype refaddr);
  1         1  
  1         622  
12              
13             our $AUTHORITY = 'cpan:PERLANCAR'; # AUTHORITY
14             our $DATE = '2022-07-21'; # DATE
15             our $DIST = 'Data-Walk-More'; # DIST
16             our $VERSION = '0.002'; # VERSION
17              
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 61     61   74 my ($opts, $val) = @_;
31              
32 61         70 my $ref = ref $val;
33 61 100       87 if ($ref eq '') {
34 39         43 local $_ = $val; $opts->{wanted}->($val);
  39         69  
35 39         115 return;
36             }
37              
38 22         34 my $refaddr = refaddr($val);
39 22 50       49 if ($_seen_refaddrs{$refaddr}++) {
40 0 0       0 return unless $opts->{follow};
41             }
42              
43 22         23 my $class;
44 22 50       39 if (blessed $val) {
45 0         0 $class = $ref;
46 0         0 $ref = reftype($val);
47             }
48              
49             RECURSE_ARRAY_HASH: {
50 22 50 66     23 last unless $ref eq 'ARRAY' || $ref eq 'HASH';
  22         42  
51 22 50 33     66 last if !$opts->{recurseobjects} && defined $class;
52              
53 22 100       36 unless ($opts->{bydepth}) {
54 21         23 local $_ = $val; $opts->{wanted}->($val);
  21         32  
55             }
56              
57 22 50       65 if ($prune) {
58 0         0 $prune = 0;
59 0         0 return;
60             }
61              
62             {
63 22         20 local $depth = $depth + 1;
  22         29  
64 22         34 local @containers = (@containers, $val);
65 22         24 local $container = $containers[-1];
66 22         33 local @indexes = (@indexes, undef);
67 22         23 local $index;
68 22 100       30 if ($ref eq 'ARRAY') {
69 17         17 for my $i (0..$#{$val}) {
  17         29  
70 44         45 $indexes[-1] = $i;
71 44         44 $index = $i;
72 44         67 _walk($opts, $val->[$i]);
73             }
74             } else { # HASH
75 5 50       21 for my $k ($opts->{sortkeys} ? (sort keys %$val) : (keys %$val)) {
76 10         13 $indexes[-1] = $k;
77 10         13 $index = $k;
78 10         16 _walk($opts, $val->{$k});
79             }
80             }
81             }
82              
83 22 100       34 if ($opts->{bydepth}) {
84 1         2 local $_ = $val; $opts->{wanted}->($val);
  1         2  
85             }
86              
87 22         44 return;
88             } # RECURSE_ARRAY_HASH
89              
90 0         0 local $_ = $val; $opts->{wanted}->($val);
  0         0  
91 0         0 return;
92             }
93              
94             sub walk {
95 7 100   7 1 10715 my $opts = ref($_[0]) eq 'HASH' ? { %{shift()} } : { wanted=>shift() };
  2         7  
96 7   50     31 $opts->{recurseobjects} //= 1;
97 7   50     22 $opts->{sortkeys} //= 1;
98              
99 7         9 local %_seen_refaddrs;
100 7         13 for my $data (@_) {
101 7         8 local $depth = 0;
102 7         17 local $prune = 0;
103 7         13 _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__