File Coverage

blib/lib/Package/Watchdog/Tracker/Watch.pm
Criterion Covered Total %
statement 48 48 100.0
branch 6 6 100.0
condition 8 8 100.0
subroutine 12 12 100.0
pod 6 6 100.0
total 80 80 100.0


line stmt bran cond sub pod time code
1             package Package::Watchdog::Tracker::Watch;
2 2     2   1253 use strict;
  2         5  
  2         122  
3 2     2   10 use warnings;
  2         4  
  2         53  
4 2     2   9 use Carp;
  2         4  
  2         142  
5 2     2   1588 use Package::Watchdog::Util;
  2         6  
  2         192  
6 2     2   1375 use Package::Watchdog::Sub::Watched;
  2         9  
  2         68  
7 2     2   13 use base 'Package::Watchdog::Tracker';
  2         3  
  2         1770  
8              
9             #{{{ POD
10              
11             =pod
12              
13             =head1 NAME
14              
15             Package::Watchdog::Tracker::Watch - Tracker to track watched subs.
16              
17             =head1 DESCRIPTION
18              
19             Tracks Package::Watchdog::Sub::Watched objects.
20              
21             =head1 ACCESSORS
22              
23             The following accessors methods are automatically generated using
24             Package::Watchdog::Util::build_accessors().
25              
26             =over 4
27              
28             =item package()
29              
30             The package being watched.
31              
32             =item react()
33              
34             The default reaction when a forbidden sub is accessed.
35              
36             =item name()
37              
38             The name of this watch.
39              
40             =back
41              
42             =head1 METHODS
43              
44             =over 4
45              
46             =cut
47              
48             #}}}
49              
50             my @ACCESSORS = qw/react name/;
51             build_accessors( @ACCESSORS );
52              
53             =item init( package => $package, stack => \@stack, react => $react, subs => $subs )
54              
55             Called by new(), arguments should be appended to the end of the arguments used w/ new().
56              
57             =cut
58              
59             sub init {
60 9     9 1 13 my $self = shift;
61 9         30 my %params = @_;
62              
63 9         25 my ( $react ) = @params{@ACCESSORS};
64 16         206 croak( "Param 'react' must be either 'die', 'warn', or a coderef." )
65 9 100 100     34 unless !$react || ( grep { /^$react$/ } qw/warn die/ ) || ref $react eq 'CODE';
      100        
66              
67 8         52 $self->$_( $params{ $_ } ) for @ACCESSORS;
68 8 100       29 $self->react( 'die' ) unless $self->react;
69 8 100       29 $self->gen_name unless $self->name;
70              
71 8         26 return $self;
72             }
73              
74              
75             =item gen_name()
76              
77             Generates a name for the watch. Called by init() when name is not specified.
78              
79             =cut
80              
81             sub gen_name {
82 5     5 1 10 my $self = shift;
83              
84 5         17 my $name = $self->package
85             . '['
86 5         14 . join(',', @{ $self->subs })
87             . ']=' . $self->react;
88              
89 5         19 $self->name( $name );
90 5         8 return $self;
91             }
92              
93             =item track_sub( $sub )
94              
95             Watch a specific sub in the watch's package.
96              
97             =cut
98              
99             sub track_sub {
100 17     17 1 27 my $self = shift;
101 17         24 my ( $sub ) = @_;
102 17         51 my $watched = Package::Watchdog::Sub::Watched->new( $self->package, $sub, $self );
103 17         59 return $self;
104             }
105              
106             =item gen_warning( $set, $level )
107              
108             FOR INTERNAL USE ONLY
109              
110             Generates the warning message when a watch is violated.
111              
112             =cut
113              
114             sub gen_warning {
115 12     12 1 15 my $self = shift;
116 12         18 my ( $context, $level ) = @_;
117 12         18 my $forbidden = $context->{ forbidden };
118 12         19 my $watched = $context->{ watched };
119              
120 12   100     44 $level ||= 'warning';
121              
122 12         57 return "Watchdog $level: sub "
123             . $forbidden->package . "::" . $forbidden->sub
124             . " was called from within "
125             . $watched->package . '::' . $watched->sub
126             . " - " . $self->name;
127             }
128              
129             =item warn( $set, $level )
130              
131             FOR INTERNAL USE ONLY
132              
133             Issue a warning when a watch is violated.
134              
135             =cut
136              
137             sub warn {
138 10     10 1 73 my $self = shift;
139 10         30 warn( $self->gen_warning( @_ ));
140 10         331 return $self;
141             }
142              
143             =item do_react( \%context )
144              
145             FOR INTERNAL USE ONLY
146              
147             Runs the custom reaction code when a watch is violated.
148              
149             =cut
150              
151             sub do_react {
152 1     1 1 16 my $self = shift;
153 1         4 $self->react->( @_ );
154 1         8 return $self;
155             }
156              
157             1;
158              
159             __END__