File Coverage

blib/lib/Object/Deadly/_unsafe.pm
Criterion Covered Total %
statement 43 44 97.7
branch 3 6 50.0
condition n/a
subroutine 13 13 100.0
pod 0 1 0.0
total 59 64 92.1


line stmt bran cond sub pod time code
1             ## no critic (Version,PodSections,Warnings,Rcs)
2             package Object::Deadly::_unsafe;
3              
4 3     3   15 use strict;
  3         5  
  3         101  
5              
6 3     3   14 use overload ();
  3         6  
  3         9224  
7             my $death = Object::Deadly->get_death;
8             overload->import(
9             map {
10             my $bad_operation = $_;
11              
12             # returns a pair.
13             $bad_operation => sub {
14              
15             ## no critic Local
16 72     72   103786 local *__ANON__ = __PACKAGE__ . "::$bad_operation";
17 72         282 $death->( $_[0], "Overloaded $bad_operation" );
18             }
19             }
20             map { split ' ' } ## no critic EmptyQuotes
21             values %overload::ops ## no critic PackageVars
22             );
23              
24             # Kill off all UNIVERSAL things and try it at several points during
25             # execution just in case someone added something along the way.
26 3     3   28 use Object::Deadly ();
  3         8  
  3         80  
27             Object::Deadly->kill_UNIVERSAL;
28              
29             # Eval CHECK and INIT blocks into existance but only if we haven't
30             # reached the main program yet. This is just to avoid the warning.
31 3     3   19 use B ();
  3         4  
  3         88  
32 3     3   23 use English '$EVAL_ERROR'; ## no critic
  3         12  
  3         25  
33              
34             BEGIN {
35 3 50   3   761 if ( not ${ B::main_start() } ) {
  3         64  
36 3         6 eval <<"CODE"; ## no critic
37 3     3   15 #line @{[__LINE__]} "@{[__FILE__]}"
  3         285  
  3         6006  
38 3     3   38 CHECK { Object::Deadly->kill_UNIVERSAL; }
39             INIT { Object::Deadly->kill_UNIVERSAL; }
40             CODE
41 3 50       283 croak $EVAL_ERROR if $EVAL_ERROR;
42             }
43             }
44              
45 3     3   593 END { Object::Deadly->kill_UNIVERSAL; }
46              
47             Object::Deadly->kill_function('AUTOLOAD');
48              
49 3     3   18 use vars '%SIMPLE_OBJECTS';
  3         6  
  3         12129  
50              
51             # DESTROY is the only legal method for these objects. It has to be.
52             sub DESTROY {
53 27     27   11016 delete $Object::Deadly::SIMPLE_OBJECTS{ Object::Deadly::refaddr $_[0] };
54 27         279 return;
55             }
56              
57             sub death { ## no critic RequireFinalReturn
58             # The common death
59 126     126 0 216 my ( $self, $bad_operation ) = @_;
60              
61 126         400 my $unsafe_implementation_class = Object::Deadly::blessed $self;
62 126         280 my $addr = Object::Deadly::refaddr $self;
63 126         646 my $name = sprintf '%s=(0x%07x)', $unsafe_implementation_class, $addr;
64 126         240 my $message;
65 126 50       494 if ( exists $SIMPLE_OBJECTS{$addr} ) {
66              
67             # Fetch the message in the object by switching the object into
68             # something that's safe.
69 126         157 my $safe_implementation_class = $unsafe_implementation_class;
70 126         864 $safe_implementation_class =~ s/\::_unsafe\z/::_safe/mx;
71              
72 126         355 bless $self, $safe_implementation_class;
73 126         173 $message = $$self; ## no critic DoubleSigils
74 126         222 bless $self, $unsafe_implementation_class;
75              
76 126         590 Object::Deadly::confess
77             "Attempt to call $bad_operation on $name: $message";
78             }
79             else {
80 0           Object::Deadly::confess "Attempt to call $bad_operation on $name";
81             }
82             }
83              
84             1;
85              
86             __END__