File Coverage

blib/lib/Tie/Static.pm
Criterion Covered Total %
statement 30 57 52.6
branch 3 28 10.7
condition 6 18 33.3
subroutine 10 13 76.9
pod 0 3 0.0
total 49 119 41.1


line stmt bran cond sub pod time code
1             package Tie::Static;
2              
3 1     1   730 use Exporter;
  1         2  
  1         84  
4             @EXPORT_OK = 'static';
5             @ISA = 'Exporter';
6             $VERSION = 0.04;
7              
8 1     1   4 use strict;
  1         2  
  1         25  
9 1     1   4 use vars qw(%call_count);
  1         1  
  1         50  
10 1     1   5 use Carp;
  1         2  
  1         525  
11              
12             sub static {
13 0     0 0 0 my $call = join "|", caller();
14            
15 0 0       0 if ($call_count{$call}) {
16 0         0 tie_all($call, @_);
17             }
18             else {
19 0 0 0     0 my @init = map {
    0          
    0          
20 0         0 (ref($_) eq "SCALAR" or ref($_) eq "REF") ? $$_
21             : (ref($_) eq "ARRAY") ? [@$_]
22             : (ref($_) eq "HASH") ? { %$_ }
23             : bad_ref($_);
24             } @_;
25            
26 0         0 tie_all($call, @_);
27            
28 0         0 foreach my $to_replace(@_) {
29 0         0 my $saved = shift @init;
30 0 0 0     0 if (ref($to_replace) eq "SCALAR" or ref($to_replace) eq "REF") {
    0          
    0          
31 0         0 $$to_replace = $saved;
32             }
33             elsif (ref($to_replace) eq "ARRAY") {
34 0         0 @$to_replace = @$saved;
35             }
36             elsif (ref($to_replace) eq "HASH") {
37 0         0 %$to_replace = %$saved;
38             }
39             else {
40 0         0 $Carp::Verbose = 1;
41 0         0 bad_ref($to_replace);
42             }
43             }
44             }
45            
46 0         0 return $call_count{$call}++;
47             }
48              
49             # The first argument is the value of $called to use, the
50             # rest are references to the variables to tie. It ties
51             # the variables to the appropriate static.
52             sub tie_all {
53 0     0 0 0 my $call = shift;
54 0         0 my $uniq = 0;
55 0         0 for (@_) {
56 0 0 0     0 if (ref($_) eq "SCALAR" or ref($_) eq "REF") {
    0          
    0          
57 0         0 tie ($$_, 'Tie::Static::Scalar', $call, $uniq++);
58             }
59             elsif (ref($_) eq "ARRAY") {
60 0         0 tie (@$_, 'Tie::Static::Array', $call, $uniq++);
61             }
62             elsif (ref($_) eq "HASH") {
63 0         0 tie (%$_, 'Tie::Static::Hash', $call, $uniq++);
64             }
65             else {
66 0         0 bad_ref($_);
67             }
68             }
69             }
70              
71             # Message for a bad reference in the argument.
72             sub bad_ref {
73 0     0 0 0 my $thing = shift;
74 0 0       0 if (my $ref = ref($thing)) {
75 0         0 croak("Cannot create static of unknown type $ref");
76             }
77             else {
78 0         0 croak("Arguments to static must be references!");
79             }
80             }
81              
82             # Implement the ties
83             foreach my $type (qw(Hash Array Scalar)) {
84             my $meth = uc($type);
85             my $pack = "Tie::Static::$type";
86 4 50 66 4   5 eval qq(
  4 50 66 4   13  
  4 50 66 4   24  
  4     4   234  
  4     4   9  
  4     4   10  
  4         5  
  4         12  
  4         22  
  4         208  
  4         7  
  4         7  
  4         167  
  4         7  
  4         9  
  4         4  
  4         12  
  4         21  
87             package $pack;
88             require Tie::$type;
89             \@$pack\::ISA = 'Tie::Std$type';
90            
91             sub TIE$meth {
92             my \$class = shift;
93             my \$call = join "|", \@_ ? \@_ : caller();
94             return \$$pack\::preserved{\$call}
95             ||= \$class->SUPER::TIE$meth();
96             }
97            
98             sub Tie::Static::TIE$meth {
99             shift;
100             unshift \@_, 'Tie::Static::$type';
101             goto &$pack\::TIE$meth;
102             }
103            
104             ) or die $@;
105             }
106              
107             1;
108              
109             __END__