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   506 use strict;
  1         2  
  1         31  
3 1     1   6 use warnings;
  1         2  
  1         29  
4 1     1   5 use Carp;
  1         2  
  1         30  
5 1     1   7 eval "use Carp::Heavy;";
  1         2  
  1         13  
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   8 my $class = shift;
20 1         2 my $globals = shift;
21 1 50       4 die if not defined $globals;
22 1 50       9 $globals = [$globals] if not ref $globals;
23              
24 1         2 my %args = @_;
25 1         4 $opt{$_} = $args{$_} for keys %args;
26              
27 1         4 foreach my $global (@$globals) {
28 1         3 my $global_esc = $global;
29 1         2 $global_esc =~ s/\\/\\\\/g;
30 1         3 $global_esc =~ s/'/\\'/g;
31              
32 1         2 my $rv;
33 1         7 my $code = "\$rv = tie($global, __PACKAGE__, \\$global, '$global_esc'); 1";
34 1 50       143 eval $code or die "Failed to tie global '$global': $@";
35             }
36             }
37              
38              
39              
40             sub TIESCALAR {
41 1     1   2 my $class = shift;
42 1   50     7 my $instance = shift || undef;
43 1         2 my $name = shift;
44              
45 1         4 my $o = bless [\$instance, $name] => $class;
46 1         3 $globals{$name} = $o;
47 1         28 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__