File Coverage

blib/lib/Devel/TrackGlobalScalar.pm
Criterion Covered Total %
statement 31 59 52.5
branch 3 18 16.6
condition 1 2 50.0
subroutine 6 12 50.0
pod 2 2 100.0
total 43 93 46.2


line stmt bran cond sub pod time code
1             package Devel::TrackGlobalScalar;
2 1     1   285 use strict;
  1         1  
  1         24  
3 1     1   3 use warnings;
  1         1  
  1         15  
4 1     1   2 use Carp;
  1         1  
  1         21  
5 1     1   4 eval "use Carp::Heavy;";
  1         1  
  1         15  
6             require Tie::Scalar;
7             our @ISA = qw(Tie::StdScalar);
8              
9             our $VERSION = '0.03';
10              
11             our %opt = (
12             track_source => 1,
13             report_write_access => 0,
14             );
15              
16             our %globals;
17              
18             sub import {
19 1     1   5 my $class = shift;
20 1         0 my $globals = shift;
21 1 50       3 die if not defined $globals;
22 1 50       3 $globals = [$globals] if not ref $globals;
23              
24 1         1 my %args = @_;
25 1         2 $opt{$_} = $args{$_} for keys %args;
26              
27 1         2 foreach my $global (@$globals) {
28 1         1 my $global_esc = $global;
29 1         1 $global_esc =~ s/\\/\\\\/g;
30 1         2 $global_esc =~ s/'/\\'/g;
31              
32 1         1 my $rv;
33 1         2 my $code = "\$rv = tie($global, __PACKAGE__, \\$global, '$global_esc'); 1";
34 1 50       48 eval $code or die "Failed to tie global '$global': $@";
35             }
36             }
37              
38              
39              
40             sub TIESCALAR {
41 1     1   1 my $class = shift;
42 1   50     2 my $instance = shift || undef;
43 1         1 my $name = shift;
44              
45 1         2 my $o = bless [\$instance, $name] => $class;
46 1         2 $globals{$name} = $o;
47 1         17 return $o;
48             }
49              
50             sub FETCH {
51             #_report($_[0], 'FETCH');
52 0     0     return ${$_[0][0]};
  0            
53             }
54              
55             sub STORE {
56 0     0     _report($_[0], 'STORE');
57 0           ${$_[0][0]} = $_[1];
  0            
58             }
59              
60             sub DESTROY {
61 0     0     _report($_[0], 'DESTROY');
62 0           undef ${$_[0][0]};
  0            
63             }
64              
65             sub _report {
66 0     0     my $obj = shift;
67 0           my $action = shift;
68              
69 0           my $global_name = $obj->[1];
70              
71 0           my $msg = Carp::longmess("${action}ing global '$global_name' at");
72 0 0         if ($opt{track_source}) {
73 0           $obj->[2] = $msg;
74             }
75 0 0         if ($opt{report_write_access}) {
76 0           print STDERR $msg . "\n";
77             }
78             }
79              
80             sub get_source {
81 0     0 1   my $self = shift;
82 0           my $key = shift;
83 0 0         print STDERR "Source tracking not enabled. Pass the track_source => 1 option when loading TrackGlobalScalar to enable\n"
84             if not $opt{track_source};
85 0 0         return '' if not @{$self} > 2;
  0            
86 0           return $self->[2];
87             }
88              
89             sub dump_all_sources {
90 0     0 1   my $class = shift;
91 0 0         print STDERR "Source tracking not enabled. Pass the track_source => 1 option when loading TrackGlobalScalar to enable\n"
92             if not $opt{track_source};
93              
94 0           my $sources = \%globals;
95 0           foreach my $key (keys %$sources) {
96 0 0         if (defined ($sources->{$key}->[2])) {
97 0           print STDERR "$key was last set at:\n" . $sources->{$key}->[2] . "\n\n";
98             }
99             }
100             }
101              
102             1;
103              
104             __END__