File Coverage

blib/lib/Class/Data/TIN.pm
Criterion Covered Total %
statement 78 81 96.3
branch 24 34 70.5
condition 6 12 50.0
subroutine 12 12 100.0
pod 4 4 100.0
total 124 143 86.7


line stmt bran cond sub pod time code
1             #-----------------------------------------------------------------
2             # Class::Data::TIN
3             #-----------------------------------------------------------------
4             # Copyright Thomas Klausner / ZSI 2001, 2002
5             # You may use and distribute this module according to the same terms
6             # that Perl is distributed under.
7             #
8             # Thomas Klausner domm@zsi.at http://domm.zsi.at
9             #
10             # $Author: domm $
11             # $Date: 2002/01/29 22:03:35 $
12             # $Revision: 1.9 $
13             #-----------------------------------------------------------------
14             # Class::Data::TIN - T_ranslucent I_nheritable N_onpolluting
15             #-----------------------------------------------------------------
16             package Class::Data::TIN;
17              
18 1     1   43648 use 5.006;
  1         3  
  1         34  
19 1     1   6 use strict;
  1         2  
  1         32  
20 1     1   5 use warnings;
  1         6  
  1         42  
21              
22             require Exporter;
23              
24 1     1   5 use Carp;
  1         2  
  1         89  
25 1     1   13330 use Data::Dumper;
  1         30383  
  1         498  
26              
27             our @ISA = qw(Exporter);
28             our @EXPORT_OK = qw(get get_classdata set set_classdata append append_classdata);
29             our $VERSION = '0.02';
30              
31             # not exported, has to be called explicitly with Class::Data::TIN->new()
32             sub new {
33 3     3 1 85 shift; # remove own ClassName 'Class::Data::TIN'
34 3         10 my $org_package=shift; # get name of package to store vars in
35 3         4 my $data;
36              
37 3 100       13 if (@_ == 1) { # one param passed
38 1         3 my $param=shift;
39 1 50       8 if (ref($param) eq 'HASH') { # is it a HASH ref ?
    0          
40 1         3 $data=$param;
41             } elsif (-e $param) { # or is it a file ?
42 0         0 $data=do $param; # TODO some error checking
43             } else { # then something is wrong
44 0         0 croak("param is neither HASH REF nor file ...");
45             }
46             } else { # more params passed, treat as HASH
47 2         5 $data={@_};
48             }
49              
50 3 50 33     23 croak("data structure must be a hashref") if ($data && ref($data) ne "HASH");
51              
52 3         7 my $tin_package=__PACKAGE__."::".$org_package;
53              
54             ### put data into TIN
55             # start eval-string
56 3         9 my $install="package $tin_package;";
57              
58             # add ISA's
59 3         255 my @isa=eval "@".$org_package."::ISA";
60 3         11 my @isa_tin;
61 3         7 foreach (@isa) {
62 2         8 push(@isa_tin,__PACKAGE__."::".$_);
63             }
64 3 100       14 $install.='our @ISA=(qw ('."@isa_tin".'));' if @isa_tin;
65              
66 3         9 $install.='our $_tin;';
67 3 50       9 $install.='$_tin=$data;' if $data;
68 3         291 eval $install;
69 3 50       13 croak $@ if $@;
70              
71             # generate accessor methods in $tin_package
72 3         13 for my $key (keys %$data) {
73 5         13 _make_accessor($tin_package,$key);
74             }
75              
76             # return empty fake pseudo obj, to make calling get/set/append easier
77             # this is /not/ blessed, in fact, its just an alias to __PACKAGE__
78 3         13 return $org_package;
79             }
80              
81             # not exported
82             sub _make_accessor {
83 17     17   32 my ($pkg,$key)=@_;
84              
85             # to enable black symbol table magic
86 1     1   14 no strict "refs";
  1         4  
  1         863  
87              
88 17         35 my $accessor=$pkg."::".$key;
89 17 100       92 return if *$accessor{CODE}; # there is allready an accessor
90              
91 14         828 my $r_tin=eval '$'."$pkg".'::_tin';
92              
93             *$accessor = sub {
94 64     64   89 my $self=shift;
95 64 100       141 $r_tin->{$key} = shift if @_;
96 64         444 return $r_tin->{$key};
97             }
98 14         144 }
99              
100             # exported, has to be called on object or class, NOT on Class::Data::TIN
101             sub get_classdata {
102 47     47 1 526 my ($self,$key)=@_;
103              
104 47   66     135 my $package=ref($self) || $self;
105 47         107 my $tin=__PACKAGE__."::".$package;
106 47 100       508 if ($tin->can($key)) {
107 44         117 return $tin->$key();
108             }
109 3         20 return;
110             }
111              
112             # alias
113             *get=*get_classdata;
114              
115             # exported, has to be called on object or class, NOT on Class::Data::TIN
116             sub set_classdata {
117 5     5 1 655 my $self=shift;
118 5   66     28 my $package=ref($self) || $self;
119              
120 5 100       185 croak "object not allowed to modify class data" if (ref($self));
121              
122 4         10 my $tin=__PACKAGE__."::".$package;
123 4         8 my ($key,$val)=@_;
124              
125             # copy on write:
126 4         14 _make_accessor($tin,$key);
127              
128 4         47 return $tin->$key($val);
129             }
130              
131             # alias
132             *set=*set_classdata;
133              
134              
135             # exported, has to be called on object or class, NOT on Class::Data::TIN
136             sub append_classdata {
137 9     9 1 19 my $self=shift;
138 9   33     41 my $package=ref($self) || $self;
139              
140 9 50       21 croak "object not allowed to modify class data" if (ref($self));
141              
142 9         19 my $tin=__PACKAGE__."::".$package;
143              
144 9         14 my $key=shift;
145              
146             # if this key is not here, there's no use appending, so use set()
147 9 100       70 unless ($tin->can($key)) {
148 1         6 return set($self,$key,@_);
149             }
150              
151             # get old value
152 8         24 my $val=$tin->$key;
153              
154 8 100       34 if (!ref($val)) {
    100          
    50          
    0          
155 2         22 $val.=shift;
156             } elsif (ref($val) eq "HASH") {
157 4         26 eval Data::Dumper->Dump([$val],['val']);
158 4         53 $val={%$val,@_};
159             } elsif (ref($val) eq "ARRAY") {
160 2         18 eval Data::Dumper->Dump([$val],['val']);
161 2         23 push(@$val,@_);
162             } elsif (ref($val) eq "CODE") {
163 0         0 croak("cannot modify code ref");
164             }
165              
166             # copy on write:
167 8         25 _make_accessor($tin,$key);
168              
169 8         23 $tin->$key($val);
170             }
171              
172             # alias
173             *append=*append_classdata;
174              
175              
176              
177              
178             1;
179             __END__