File Coverage

blib/lib/immutable/map.pm
Criterion Covered Total %
statement 55 56 98.2
branch 2 2 100.0
condition n/a
subroutine 21 22 95.4
pod 0 7 0.0
total 78 87 89.6


line stmt bran cond sub pod time code
1 1     1   7 use strict; use warnings;
  1     1   2  
  1         33  
  1         5  
  1         1  
  1         40  
2             package immutable::map;
3              
4              
5              
6             package immutable::map::tied;
7 1     1   5 use base 'Hash::Ordered';
  1         2  
  1         618  
8              
9 1     1   3657 use Carp 'croak';
  1         3  
  1         134  
10              
11             # Prevent tied changes to immutable::map.
12             # Mutation operations must use method calls which will return a new map.
13              
14             sub STORE {
15 1     1   201 croak
16             "Not valid to set a key/value on an immutable::map object.\n" .
17             "Try '->set(\$key, \$val)' which returns a new immutable::map.\n";
18             }
19              
20             sub DELETE {
21 1     1   714 croak
22             "Not valid to delete a key from an immutable::map object.\n" .
23             "Try '->del(\$key)' which returns a new immutable::map.\n";
24             }
25              
26             sub CLEAR {
27 0     0   0 croak "Invalid CLEAR called on immutable::map object.\n";
28             }
29              
30              
31              
32             package immutable::map;
33              
34 1     1   6 use Carp 'croak';
  1         2  
  1         38  
35              
36 1     1   5 use Scalar::Util 'refaddr';
  1         7  
  1         187  
37              
38             use overload
39             q{""} => sub {
40 2     2   679 my ($self) = @_;
41 2         3 "<${\ __PACKAGE__} ${\ $self->size} ${\ refaddr $self}>";
  2         18  
  2         6  
  2         30  
42             },
43             q{0+} => sub {
44 1     1   6 $_[0]->size;
45             },
46             q{bool} => sub {
47 3     3   7 !! $_[0]->size;
48             },
49 1     1   7 fallback => 1;
  1         2  
  1         9  
50              
51             sub new {
52 2     2 0 5 my $class = shift;
53 2         14 tie my %hash, 'immutable::map::tied', @_;
54 2         40 bless \%hash, $class;
55             }
56              
57             sub get {
58 3     3 0 1329 tied(%{$_[0]})->get($_[1]);
  3         15  
59             }
60              
61             sub set {
62 3     3 0 944 my $self = shift;
63 3         18 tie my %hash, 'immutable::map::tied', %$self;
64 3 100       206 if (@_ == 2) {
65 2         7 tied(%hash)->set(@_);
66             }
67             else {
68 1         8 tied(%hash)->push(@_);
69             }
70 3         48 bless \%hash, ref($self);
71             }
72              
73             sub del {
74 1     1 0 654 my $self = shift;
75 1         4 tie my %hash, 'immutable::map::tied', %$self;
76 1         58 tied(%hash)->delete(@_);
77 1         25 bless \%hash, ref($self);
78             }
79              
80             # sub equal_to {
81             # my ($self, $iobj) = @_;
82             # return unless ref($self) eq ref($iobj);
83             # croak "equal_to";
84             # }
85              
86             # sub clone {
87             # shift->set();
88             # }
89              
90             sub id {
91 4     4 0 765 refaddr($_[0]);
92             }
93              
94             sub size {
95 10     10 0 15 0 + @{tied(%{$_[0]})->[1]};
  10         14  
  10         116  
96             }
97              
98             sub is_empty {
99 3     3 0 632 $_[0]->size == 0;
100             }
101              
102             sub DESTROY {
103 6     6   1526 untie(%{$_[0]});
  6         164  
104             }
105              
106             # TODO should not proxy mutating methods.
107             our $AUTOLOAD;
108             sub AUTOLOAD {
109 2     2   12 my $self = shift;
110 2         14 (my $method = $AUTOLOAD) =~ s/^.*:://;
111 2         10 tied(%$self)->$method(@_);
112             }
113              
114             1;