File Coverage

blib/lib/Devel/Walk.pm
Criterion Covered Total %
statement 32 32 100.0
branch 15 16 93.7
condition 5 5 100.0
subroutine 5 5 100.0
pod 1 1 100.0
total 58 59 98.3


line stmt bran cond sub pod time code
1             package Devel::Walk;
2              
3 6     6   1058440 use 5.010000;
  6         24  
4 6     6   39 use strict;
  6         35  
  6         220  
5 6     6   66 use warnings;
  6         9  
  6         565  
6              
7 6     6   45 use Scalar::Util qw( refaddr reftype );
  6         19  
  6         4182  
8              
9             require Exporter;
10              
11             our @ISA = qw(Exporter);
12             our %EXPORT_TAGS = ( 'all' => [ qw( walk unstorable ) ] );
13             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
14             our @EXPORT = qw( walk );
15              
16             our $VERSION = '0.04';
17              
18             our $TOP = 1;
19             our %SEEN;
20              
21             sub DEBUG () { 0 }
22              
23             sub walk
24             {
25 102     102 1 612532 my( $obj, $sub, $loc ) = @_;
26             # Thank you tobyink@cpan.org for pointing out refaddr()
27 102         180 my $addr = refaddr( $obj );
28              
29 102   100     230 $loc ||= '$o';
30 102 100       244 return unless $sub->($loc, $obj);
31              
32 68         13388 my $r = reftype $obj;
33 68 100       172 return unless $r;
34 55 100       172 return if $SEEN{$addr};
35              
36 54         73 DEBUG and warn "$loc is $r";
37              
38 54         111 my $was_top = $TOP;
39 54         103 local $TOP = 0;
40 54 100 100     286 if( 'HASH' eq $r ) {
    100          
    100          
41 23         75 local $SEEN{ $addr } = 1;
42 23 100       63 $loc .= "->" if $was_top;
43 23         99 foreach my $key ( keys %$obj ) {
44 41         5661 walk( $obj->{$key}, $sub, $loc."{$key}" );
45             }
46             }
47             elsif( 'ARRAY' eq $r ) {
48 10         57 local $SEEN{ $addr } = 1;
49 10 50       30 $loc .= "->" if $was_top;
50 10         37 for( my $q=0; $q<=$#$obj; $q++ ) {
51 40         9948 walk( $obj->[$q], $sub, $loc."[$q]" );
52             }
53             }
54             elsif( 'REF' eq $r or 'SCALAR' eq $r ) {
55 13         36 local $SEEN{ $addr } = 1;
56 13         90 walk( $$obj, $sub, "\$\${$loc}" );
57             }
58              
59             }
60              
61              
62             1;
63              
64             __END__