File Coverage

blib/lib/Class/Data/Localize.pm
Criterion Covered Total %
statement 40 43 93.0
branch 11 12 91.6
condition 5 6 83.3
subroutine 7 7 100.0
pod n/a
total 63 68 92.6


line stmt bran cond sub pod time code
1             package Class::Data::Localize;
2              
3 3     3   54355 use strict qw(vars subs);
  3         6  
  3         122  
4 3     3   12 use vars qw($VERSION);
  3         4  
  3         178  
5             $VERSION = '0.03_2';
6              
7 3     3   1359 use ReleaseAction ();
  3         701  
  3         1324  
8              
9             our $warn_redefine = 1;
10              
11             our %methods;
12             %methods = (
13             'lazy_default' => sub {
14             my ($declaredclass,$attr,$code) = @_;
15             my $default;
16             $default = sub {
17             my $wantclass = ref($_[0]) || $_[0];
18             $_[1] = $code->() unless defined $_[1];
19              
20             if(@_==3) {
21             $_[2] = ReleaseAction->new(sub {
22             local $warn_redefine;
23             $methods{'make_accessor'}->($wantclass,$attr,$default);
24             });
25             }
26             local $warn_redefine;
27             $methods{'mk_classdata'}->($wantclass,$attr,$_[1]);
28             shift;
29             return $wantclass->$attr(@_);
30             };
31             return $default;
32             },
33              
34             'class_accessor' => sub {
35             my ($declaredclass, $attribute,$data) = @_;
36              
37             my $accessor;
38             $accessor = sub {
39 40   66 40   1357 my $wantclass = ref($_[0]) || $_[0];
40 40 100       70 if(@_==3) {
41 6         11 my $current = $data;
42 6         4 my $stacked = $_[2]; # maybe a lazy default release action
43             $_[2] = ReleaseAction->new(sub {
44 5     5   1471 $data = $current;
45 5         21 undef($stacked);
46 6         31 });
47              
48 6 50       30 if($wantclass ne $declaredclass){
49 0         0 shift();
50 0         0 $methods{'mk_classdata'}->($wantclass,$attribute,$data);
51 0         0 return $wantclass->$attribute(@_);
52             }
53             }
54             else {
55 34 100 100     112 if(@_>1 && $wantclass ne $declaredclass) {
56 4         4 shift();
57 4         7 $methods{'mk_classdata'}->($wantclass,$attribute);
58 4         9 return $wantclass->$attribute(@_)
59             }
60             }
61 36 100       57 $data = $_[1] if @_>1;
62 36         100 return $data;
63             };
64             return $accessor;
65             },
66              
67             'make_accessor' => sub {
68             my ($declaredclass,$attribute,$accessor) = @_;
69              
70             my $alias = "_${attribute}_accessor";
71             if($warn_redefine) {
72             *{$declaredclass.'::'.$attribute} = $accessor;
73             *{$declaredclass.'::'.$alias} = $accessor;
74             }
75             else {
76 3     3   17 no warnings 'redefine';
  3         5  
  3         850  
77             *{$declaredclass.'::'.$attribute} = $accessor;
78             *{$declaredclass.'::'.$alias} = $accessor;
79             }
80             },
81              
82             'mk_classdata' => sub {
83 20     20   90 my ($declaredclass, $attribute,@args) = @_;
84              
85 20 100       34 if( ref $declaredclass ) {
86 1         8 require Carp;
87 1         159 Carp::croak("mk_classdata() is a class method, not an object method");
88             }
89 19         29 my ($accessor);
90 19 100       25 if(@args > 1) {
91 3         5 my %args = @args;
92 3         4 my $code = $args{'default'};
93              
94 3         7 $methods{'mk_classdata'}->($declaredclass, $attribute, undef);
95 3         5 $accessor = $methods{'lazy_default'}->($declaredclass, $attribute, $code);
96 3         2 local $warn_redefine;
97 3         4 $methods{'make_accessor'}->($declaredclass,$attribute,$accessor)
98             }
99             else {
100 16         32 $accessor = $methods{'class_accessor'}->($declaredclass, $attribute, $args[0]);
101 16         29 $methods{'make_accessor'}->($declaredclass,$attribute,$accessor)
102             }
103             }
104             );
105              
106             *mk_classdata = $methods{'mk_classdata'};
107              
108             1;
109              
110             __END__