File Coverage

blib/lib/Tie/RefHash/Weak.pm
Criterion Covered Total %
statement 60 61 98.3
branch 12 14 85.7
condition n/a
subroutine 14 14 100.0
pod 2 2 100.0
total 88 91 96.7


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package Tie::RefHash::Weak;
4 4     4   109148 use base qw/Tie::RefHash Exporter/;
  4         12  
  4         4415  
5              
6 4     4   44325 use strict;
  4         12  
  4         134  
7 4     4   22 use warnings;
  4         15  
  4         121  
8              
9 4     4   21 use warnings::register;
  4         7  
  4         574  
10              
11 4     4   6829 use overload ();
  4         4198  
  4         98  
12              
13 4     4   25 use B qw/svref_2object CVf_CLONED/;
  4         9  
  4         515  
14              
15             our $VERSION = 0.09;
16             our @EXPORT_OK = qw 'fieldhash fieldhashes';
17             our %EXPORT_TAGS = ( all => \@EXPORT_OK );
18              
19 4     4   22 use Scalar::Util qw/weaken reftype/;
  4         8  
  4         309  
20 4     4   5030 use Variable::Magic qw/wizard cast getdata/;
  4         5984  
  4         2212  
21              
22             my $wiz = wizard free => \&_clear_weakened_sub, data => \&_add_magic_data;
23              
24             sub _clear_weakened_sub {
25 1061     1061   36080 my ( $key, $objs ) = @_;
26 1061         1404 local $@;
27 1061 50       1109 foreach my $self ( grep { defined } @{ $objs || [] } ) {
  2085         4296  
  1061         2473  
28 2085         12708 eval { $self->_clear_weakened($key) }; # support subclassing
  2085         3866  
29             }
30             }
31              
32             sub _add_magic_data {
33 1061     1061   1192 my ( $key, $objects ) = @_;
34 1061         2401 $objects;
35             }
36              
37             sub _clear_weakened {
38 2085     2085   2483 my ( $self, $key ) = @_;
39              
40 2085         4464 $self->DELETE( $key );
41             }
42              
43             sub STORE {
44 3111     3111   35928 my($s, $k, $v) = @_;
45              
46 3111 100       5191 if (ref $k) {
47             # make sure we use the same function that RefHash is using for ref keys
48 2342         3955 my $kstr = Tie::RefHash::refaddr($k);
49 2342         4482 my $entry = [$k, $v];
50              
51 2342         4961 weaken( $entry->[0] );
52              
53 2342         2324 my $objects;
54              
55 2342 100       5421 if ( reftype $k eq 'CODE' ) {
56 295 50       1250 unless ( svref_2object($k)->CvFLAGS & CVf_CLONED ) {
57 0         0 warnings::warnif("Non closure code references never get garbage collected: $k");
58             } else {
59 295 100       1693 $objects = &getdata ( $k, $wiz )
60             or &cast( $k, $wiz, ( $objects = [] ) );
61             }
62             } else {
63 2047 100       6973 $objects = &getdata( $k, $wiz )
64             or &cast( $k, $wiz, ( $objects = [] ) );
65             }
66              
67 2342         3417 @$objects = grep { defined } @$objects;
  1538         3956  
68              
69 2342 100       3796 unless ( grep { $_ == $s } @$objects ) {
  1538         4120  
70 2085         2683 push @$objects, $s;
71 2085         4106 weaken($objects->[-1]);
72             }
73              
74 2342         5976 $s->[0]{$kstr} = $entry;
75             }
76             else {
77 769         1201 $s->[1]{$k} = $v;
78             }
79              
80 3111         8787 $v;
81             }
82              
83             sub fieldhash(\%) {
84 1     1 1 7 tie %{$_[0]}, __PACKAGE__;
  1         14  
85 1         12 return $_[0];
86             }
87              
88             sub fieldhashes {
89 2     2 1 1712 tie %{$_}, __PACKAGE__ for @_;
  4         31  
90 2         27 return @_;
91             }
92              
93             __PACKAGE__
94              
95             __END__