File Coverage

blib/lib/selfvars.pm
Criterion Covered Total %
statement 89 129 68.9
branch 8 10 80.0
condition 10 15 66.6
subroutine 25 50 50.0
pod n/a
total 132 204 64.7


line stmt bran cond sub pod time code
1             package selfvars;
2 5     5   10827 use 5.005;
  5         15  
  5         182  
3 5     5   24 use strict;
  5         8  
  5         358  
4 5     5   46 use vars qw( $VERSION $self @args %opts %hopts );
  5         9  
  5         1157  
5              
6             BEGIN {
7 5     5   649 $VERSION = '0.32';
8             }
9              
10             sub import {
11 6     6   166 my $class = shift; # Oooh, the irony!
12 6 100       47 my %vars = (-self => undef, -args => undef, -opts => undef, -hopts => undef) unless @_;
13              
14 6         30 while (@_) {
15 7         7 my $key = shift;
16 7 50 33     33 if (@_ and $_[0] !~ /^-/) {
17 7         23 $vars{$key} = shift;
18             }
19             else {
20 0         0 $vars{$key} = undef;
21             }
22             }
23              
24 6         14 my $pkg = caller;
25              
26 5     5   27 no strict 'refs';
  5         10  
  5         1617  
27 6         31 my %map = (self => \$self, args => \@args, opts => \%opts, hopts => \%hopts);
28 6         36 while (my ($sym, $var) = each %map) {
29 24 100       60 exists $vars{"-$sym"} or next;
30 23 100       63 $vars{"-$sym"} = $sym unless defined $vars{"-$sym"};
31 23         24 *{"$pkg\::$vars{qq[-$sym]}"} = $var;
  23         896  
32             }
33             }
34              
35             package selfvars::self;
36              
37             sub TIESCALAR {
38 5     5   11 my $x;
39 5         25 bless \$x => $_[0];
40             }
41              
42             sub FETCH {
43 65     65   1055 my $level = 1;
44 65         88 my @c = ();
45 65   100     189 while ( !defined( $c[3] ) || $c[3] eq '(eval)' ) {
46 96         106 @c = do {
47             package DB;
48 96         115 @DB::args = ();
49 96         524 caller($level);
50             };
51 96         467 $level++;
52             }
53 65         403 $DB::args[0];
54             }
55              
56             sub STORE {
57 0     0   0 require Carp;
58 0         0 Carp::croak('Modification of a read-only $self attempted');
59             }
60              
61             package selfvars::args;
62 5     5   11515 use Tie::Array ();
  5         8933  
  5         114  
63 5     5   39 use vars qw(@ISA);
  5         11  
  5         190  
64 5     5   2109 BEGIN { @ISA = 'Tie::Array' }
65              
66             sub _args {
67 22     22   25 my $level = 2;
68 22         128 my @c;
69 22   66     59 while ( !defined( $c[3] ) || $c[3] eq '(eval)' ) {
70 22         23 @c = do {
71             package DB;
72 22         28 @DB::args = ();
73 22         118 caller($level);
74             };
75 22         107 $level++;
76             }
77 22         109 \@DB::args;
78             }
79              
80 0     0   0 sub readonly { require Carp; Carp::croak('Modification of a read-only @args attempted'); }
  0         0  
81              
82 5     5   8 sub TIEARRAY { my $x; bless \$x => $_[0] }
  5         75  
83 11     11   80 sub FETCHSIZE { scalar $#{ _args() } }
  11         26  
84 0     0   0 sub STORESIZE { goto &readonly } # $#{ _args() } = $_[1] + 1;
85 0     0   0 sub STORE { _args()->[ $_[1] + 1 ] = $_[2] }
86 11     11   19 sub FETCH { _args()->[ $_[1] + 1 ] }
87 0     0   0 sub CLEAR { goto &readonly } # $#{ _args() } = 0;
88 0     0   0 sub POP { goto &readonly } # my $o = _args(); (@$o > 1) ? pop(@$o) : undef
89 0     0   0 sub PUSH { goto &readonly } # my $o = _args(); push( @$o, @_ )
90 0     0   0 sub SHIFT { goto &readonly } # my $o = _args(); splice( @$o, 1, 1 )
91 0     0   0 sub UNSHIFT { goto &readonly } # my $o = _args(); unshift( @$o, @_ )
92 0     0   0 sub DELETE { goto &readonly } # my $o = _args(); delete $o->[ $_[1] + 1 ]
93 0     0   0 sub SPLICE { goto &readonly }
94             # my $ob = shift;
95             # my $sz = $ob->FETCHSIZE;
96             # my $off = @_ ? shift : 0;
97             # $off += $sz if $off < 0;
98             # my $len = @_ ? shift : $sz - $off;
99             # splice( @$ob, $off + 1, $len, @_ );
100              
101             BEGIN {
102 5     5   14 local $@;
103 5 50   0   9818 eval q{
  0         0  
  0         0  
104             sub EXISTS {
105             my $o = _args(); exists $o->[ $_[1] + 1 ]
106             }
107             } if $] >= 5.006;
108             }
109              
110             package selfvars::opts;
111              
112             sub _opts {
113 1     1   2 my $level = 2;
114 1         1 my @c;
115 1   66     5 while ( !defined( $c[3] ) || $c[3] eq '(eval)' ) {
116 1         1 @c = do {
117             package DB;
118 1         2 @DB::args = ();
119 1         7 caller($level);
120             };
121 1         6 $level++;
122             }
123 1         5 $DB::args[1];
124             }
125              
126 5     5   21 sub TIEHASH { my $x; bless \$x => $_[0] }
  5         16  
127 1     1   11 sub FETCH { _opts()->{ $_[1] } }
128 0     0   0 sub STORE { _opts()->{ $_[1] } = $_[2] }
129 0     0   0 sub FIRSTKEY { my $o = _opts(); my $a = scalar keys %$o; each %$o }
  0         0  
  0         0  
130 0     0   0 sub NEXTKEY { my $o = _opts(); each %$o }
  0         0  
131 0     0   0 sub EXISTS { my $o = _opts(); exists $o->{$_[1]} }
  0         0  
132 0     0   0 sub DELETE { my $o = _opts(); delete $o->{$_[1]} }
  0         0  
133 0     0   0 sub CLEAR { my $o = _opts(); %$o = () }
  0         0  
134 0     0   0 sub SCALAR { my $o = _opts(); scalar %$o }
  0         0  
135              
136             package selfvars::hopts;
137              
138             sub _opts {
139 1     1   3 my $level = 2;
140 1         2 my @c;
141 1   66     6 while ( !defined( $c[3] ) || $c[3] eq '(eval)' ) {
142 1         3 @c = do {
143             package DB;
144 1         2 @DB::args = ();
145 1         7 caller($level);
146             };
147 1         8 $level++;
148             }
149 1         2 shift @DB::args;
150 1         4 @DB::args;
151             }
152              
153 1     1   6 sub readonly { require Carp; Carp::croak('Modification of a read-only %hopts attempted'); }
  1         177  
154              
155 5     5   8 sub TIEHASH { my $x; bless \$x => $_[0] }
  5         156  
156 1     1   5 sub FETCH { my (%o) = _opts(); $o{ $_[1] } }
  1         11  
157 1     1   13 sub STORE { goto &readonly }
158 0     0     sub FIRSTKEY { my (%o) = _opts(); my $a = scalar keys %o; each %o }
  0            
  0            
159 0     0     sub NEXTKEY { }
160 0     0     sub EXISTS { my (%o) = _opts(); exists $o{$_[1]} }
  0            
161 0     0     sub DELETE { goto &readonly }
162 0     0     sub CLEAR { goto &readonly }
163 0     0     sub SCALAR { my (%o) = _opts(); scalar %o }
  0            
164              
165              
166             package selfvars;
167              
168             BEGIN {
169 5     5   32 tie $self => __PACKAGE__ . '::self';
170 5         21 tie @args => __PACKAGE__ . '::args';
171 5         23 tie %opts => __PACKAGE__ . '::opts';
172 5         17 tie %hopts => __PACKAGE__ . '::hopts';
173             }
174              
175             1;
176              
177             __END__