File Coverage

blib/lib/Devel/EnforceEncapsulation.pm
Criterion Covered Total %
statement 70 70 100.0
branch 10 10 100.0
condition 4 4 100.0
subroutine 17 17 100.0
pod 2 2 100.0
total 103 103 100.0


line stmt bran cond sub pod time code
1             #######################################################################
2             # $URL: svn+ssh://equilibrious@equilibrious.net/home/equilibrious/Mirror/medialandscape/repos/clotho/Devel-EnforceEncapsulation/lib/Devel/EnforceEncapsulation.pm $
3             # $Date: 2014-03-27 18:57:41 -0500 (Thu, 27 Mar 2014) $
4             # $Author: equilibrious $
5             # $Revision: 3356 $
6             ########################################################################
7              
8             package Devel::EnforceEncapsulation;
9              
10 1     1   22188 use warnings;
  1         4  
  1         37  
11 1     1   7 use strict;
  1         1  
  1         42  
12 1     1   878 use English qw(-no_match_vars);
  1         4522  
  1         6  
13 1     1   518 use Carp;
  1         2  
  1         83  
14 1     1   2013 use overload;
  1         1422  
  1         8  
15              
16             our $VERSION = '0.51';
17              
18             sub apply_to {
19 7     7 1 4563 my $pkg = shift;
20 7         13 my $dest_pkg = shift;
21 7   100     45 my $opts = shift || {};
22              
23 7   100     36 $opts->{policy} ||= 'croak';
24 7 100       10 if (!eval { $pkg->can('_deref_overload_' . $opts->{policy}) }) {
  7         67  
25 1         208 croak "Unknown encapsulation policy '$opts->{policy}'";
26             }
27              
28             ## no critic(ProhibitStringyEval,RequireCarping)
29 6         17 my $fn = __PACKAGE__ . '::_deref_overload_' . $opts->{policy};
30 6         22 my $overloads = join q{,}, map { "'$_' => \\&$fn" } $pkg->_ops;
  30         95  
31 1     1   8 eval "{package $dest_pkg; use overload $overloads, fallback => 1;}";
  1     1   2  
  1     1   10  
  1     1   6  
  1     1   1  
  1         6  
  1         9  
  1         3  
  1         7  
  1         6  
  1         2  
  1         5  
  1         7  
  1         2  
  1         15  
  6         885  
32 6 100       27 die $EVAL_ERROR if $EVAL_ERROR;
33 5         18 return;
34             }
35              
36             sub remove_from {
37 3     3 1 1609 my $pkg = shift;
38 3         6 my $dest_pkg = shift;
39              
40             ## no critic(ProhibitStringyEval,RequireCarping)
41 3         12 my $overloads = join q{,}, map { "'$_'" } $pkg->_ops;
  15         42  
42 1     1   8 eval "{package $dest_pkg; no overload $overloads, 'fallback';}";
  1     1   2  
  1         7  
  1         8  
  1         2  
  1         7  
  3         255  
43 3 100       17 die $EVAL_ERROR if $EVAL_ERROR;
44 2         5 return;
45             }
46              
47             ## possible callbacks to be installed via overload ##
48              
49             sub _deref_overload_croak {
50 53     53   11115 my $self = shift;
51              
52 53         88 my $caller_pkg = caller;
53 53 100       267 if (!$self->isa($caller_pkg)) {
54 16         761 my $pkg = ref $self;
55 16         2054 croak "Illegal attempt to access $pkg internals from $caller_pkg";
56             }
57 37         162 return $self;
58             }
59              
60             sub _deref_overload_carp {
61 3     3   57 my $self = shift;
62              
63 3         4 my $caller_pkg = caller;
64 3 100       22 if (!$self->isa($caller_pkg)) {
65 1         3 my $pkg = ref $self;
66 1         143 carp "Illegal attempt to access $pkg internals from $caller_pkg";
67             }
68 3         60 return $self;
69             }
70              
71             # get a list of overloadable derefs ('%{}', '@{}', '${}', ...)
72             sub _ops {
73 9     9   13 my $pkg = shift;
74              
75             ## no critic(ProhibitPackageVars)
76 9         75 return split m/\s/xms, $overload::ops{dereferencing};
77             }
78              
79             1;
80              
81             __END__