File Coverage

blib/lib/UNIVERSAL/Object/Immutable.pm
Criterion Covered Total %
statement 41 41 100.0
branch 15 16 93.7
condition 12 12 100.0
subroutine 11 11 100.0
pod 1 1 100.0
total 80 81 98.7


line stmt bran cond sub pod time code
1             package UNIVERSAL::Object::Immutable;
2             # ABSTRACT: Another useful base class
3 3     3   206708 use 5.008;
  3         44  
4 3     3   17 use strict;
  3         8  
  3         68  
5 3     3   14 use warnings;
  3         6  
  3         103  
6              
7 3     3   15 use Carp ();
  3         12  
  3         63  
8 3     3   3762 use overload ();
  3         3016  
  3         69  
9 3     3   1641 use Hash::Util ();
  3         8698  
  3         71  
10 3     3   19 use Scalar::Util ();
  3         6  
  3         52  
11              
12 3     3   1361 use UNIVERSAL::Object;
  3         7  
  3         273  
13              
14             our $VERSION = '0.17';
15             our $AUTHORITY = 'cpan:STEVAN';
16              
17 3     3   1273 our @ISA; BEGIN { @ISA = ('UNIVERSAL::Object') }
18              
19             sub new {
20 10     10 1 455 my $class = shift;
21 10         47 my $self = $class->SUPER::new( @_ );
22 10         35 my $repr = overload::StrVal($self);
23              
24 10 100 100     124 if ( $repr =~ /\=HASH\(0x/ ) {
    100 100        
    100          
    100          
25 4         19 Hash::Util::lock_hash( %$self );
26             }
27             elsif ( $repr =~ /\=ARRAY\(0x/ ) {
28 1         7 Internals::SvREADONLY( @$self, 1 );
29             }
30             elsif ( $repr =~ /\=SCALAR\(0x/ or $repr =~ /\=REF\(0x/ or $repr =~ /\=REGEXP\(0x/ ) {
31 3         15 Internals::SvREADONLY( $$self, 1 );
32             }
33             elsif ( $repr =~ /\=CODE\(0x/ ) {
34             # NOTE: do nothing here, because – ignoring
35             # closures – CODE refs are immutable anyway
36             }
37             else {
38 1         234 Carp::confess('Invalid BLESS args for '.Scalar::Util::blessed($self).', unsupported REPR type ('.Scalar::Util::reftype($self).')');
39             }
40              
41 9         110 return $self;
42             }
43              
44             sub DESTROY {
45 9     9   24099 my $self = $_[0];
46 9         28 my $repr = overload::StrVal($self);
47              
48             # reverse the locks for all types ...
49 9 100 100     105 if ( $repr =~ /\=HASH\(0x/ ) {
    100 100        
    100          
50 4         23 Hash::Util::unlock_hash( %$self );
51             }
52             elsif ( $repr =~ /\=ARRAY\(0x/ ) {
53 1         4 Internals::SvREADONLY( @$self, 0 );
54             }
55             elsif ( $repr =~ /\=SCALAR\(0x/ or $repr =~ /\=REF\(0x/ or $repr =~ /\=REGEXP\(0x/ ) {
56 3         11 Internals::SvREADONLY( $$self, 0 );
57             }
58             else {
59             # nothing here ...
60             }
61              
62 9 50       177 $self->can('DEMOLISH') && UNIVERSAL::Object::Util::DEMOLISHALL( $self );
63 9         296 return;
64             }
65              
66             1;
67              
68             __END__