File Coverage

blib/lib/Devel/Walk/Unstorable.pm
Criterion Covered Total %
statement 45 47 95.7
branch 12 14 85.7
condition 6 11 54.5
subroutine 11 11 100.0
pod 5 5 100.0
total 79 88 89.7


line stmt bran cond sub pod time code
1             package Devel::Walk::Unstorable;
2              
3 2     2   93124 use strict;
  2         4  
  2         83  
4 2     2   11 use warnings;
  2         3  
  2         119  
5              
6 2     2   543 use Devel::Walk ();
  2         5  
  2         1650  
7              
8             require Exporter;
9              
10             our @ISA = qw(Exporter);
11             our %EXPORT_TAGS = ( 'all' => [ qw( unstorable ) ] );
12             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
13             our @EXPORT = qw( unstorable );
14             our $VERSION = '0.02';
15              
16             ###############################################
17             sub unstorable
18             {
19 1     1 1 730 my( $obj, $name ) = @_;
20 1         5 my $S = Devel::Walk::Unstorable->new;
21 1         5 $S->walk( $obj, $name );
22 1         4 return $S->list;
23             }
24              
25             ###############################################
26             sub new
27             {
28 2     2 1 216454 my $package = shift;
29 2         7 return bless {@_}, $package;
30             }
31              
32             sub walk
33             {
34 2     2 1 10 my( $self, $obj, $name ) = @_;
35 2         15 local $self->{LAST};
36 2   50     17 $self->{list} ||= [];
37 2     38   15 Devel::Walk::walk( $obj, sub { $self->__unstorable( @_ ); }, $name );
  38         98  
38 0         0 push @{ $self->{list} }, $self->{LAST} if defined $self->{LAST} and @{ $self->{list} } and
  0         0  
39 2 0 33     18 $self->{list}[-1] ne $self->{LAST};
      33        
40             }
41              
42 2     2 1 605 sub list { @{ $_[0]->{list} } }
  2         17  
43              
44             sub __deepest
45             {
46 38     38   82 my( $self, $old, $new ) = @_;
47 38 100       93 return unless defined $old;
48 34         84 my $ol = length( $old );
49             # $old = '$something->{one}'
50             # $new = '$something->{one}[0]'
51             # $old is not deepest
52 34 100       116 return if substr( $new, 0, $ol ) eq $old;
53              
54             # $old = '$something->{one}'
55             # $new = '$${$something->{one}}{more}'
56             # $old is not deepest
57 8 100       197 return if $new =~ /^\$\$\{\Q$old\E\}/;
58             # $old = '$something->{one}'
59             # $new = '$something->{two}'
60             # $old is deepest
61             # warn "deepest='$old'";
62 4         15 return 1;
63             }
64              
65             sub __unstorable
66             {
67 38     38   80 my( $self, $loc, $obj ) = @_;
68 38         166 require 'Storable.pm';
69 38 100       91 if( $self->__deepest( $self->{LAST}, $loc ) ) {
70             # warn "deepest=$self->{LAST}";
71 4         6 push @{ $self->{list} }, $self->{LAST};
  4         15  
72 4         15 $self->{LAST} = undef;
73             }
74              
75 38 100       107 if( $self->check( $loc, $obj ) ) {
76             # warn "$loc is unstorable";
77 20         3917 $self->{LAST} = $loc;
78 20         107 return 1;
79             }
80             else {
81             # warn "$loc is storable";
82             }
83 18         81 return;
84             }
85              
86             sub check
87             {
88 38     38 1 74 my( $self, $loc, $obj ) = @_;
89 38 100 100     102 return 1 if ref( $obj ) and not eval { $SIG{__DIE__} = 'DEFAULT'; Storable::freeze( $obj ); 1; };
  26         73  
  26         84  
  6         381  
90 18         48 return;
91             }
92              
93             1;
94              
95             __END__