File Coverage

blib/lib/Class/Accessor/WithDefault.pm
Criterion Covered Total %
statement 69 75 92.0
branch 19 30 63.3
condition 10 21 47.6
subroutine 11 11 100.0
pod 2 6 33.3
total 111 143 77.6


line stmt bran cond sub pod time code
1             package Class::Accessor::WithDefault;
2 2     2   1849 use base qw/Class::Accessor/;
  2         3  
  2         2054  
3 2     2   5143 use 5.006;
  2         8  
  2         1973  
4              
5             our $VERSION = '0.23';
6              
7             sub mk_accessors {
8 2     2 1 1736 my $self = shift;
9 2         4 my @fields;
10 2         5 foreach (@_) {
11 5 100       19 if ( ref $_ eq 'HASH' ) {
12 3         5 $self->mk_default( %{$_} );
  3         19  
13             }
14             else {
15 2         4 push @fields, $_;
16             }
17             }
18 2         15 $self->SUPER::mk_accessors(@fields);
19             }
20              
21             sub mk_ro_accessors {
22 1     1 1 87 my $self = shift;
23 1         1 my @fields;
24 1         3 foreach (@_) {
25 1 50       5 if ( ref $_ eq 'HASH' ) {
26 1         2 $self->mk_ro_default( %{$_} );
  1         8  
27             }
28             else {
29 0         0 push @fields, $_;
30             }
31             }
32 1         9 $self->SUPER::mk_ro_accessors(@fields);
33             }
34              
35             sub mk_default {
36 3     3 0 8 my ( $self, %args ) = @_;
37 3         19 $self->_make_default( "rw", %args );
38             }
39              
40             sub mk_ro_default {
41 1     1 0 3 my ( $self, %args ) = @_;
42 1         4 $self->_make_default( 'ro', %args );
43             }
44              
45             ## make accessors and set the default value
46             ## mostly copied from Class::Accessor::_mk_accessors
47             sub _make_default {
48 4     4   11 my ( $self, $access, %args ) = @_;
49 4   33     24 my $class = ref $self || $self;
50 4   66     19 my $ra = $access eq 'rw' || $access eq 'ro';
51 4   66     20 my $wa = $access eq 'rw' || $access eq 'wo';
52              
53 4         17 while ( my ( $field, $value ) = each %args ) {
54 4         20 my $accessor_name = $self->accessor_name_for($field);
55 4         33 my $mutator_name = $self->mutator_name_for($field);
56 4 50 33     35 if ( $accessor_name eq 'DESTROY' or $mutator_name eq 'DESTROY' ) {
57 0         0 $self->_carp(
58             "Having a data accessor named DESTROY in '$class' is unwise.");
59             }
60              
61 4 100       10 if ( $accessor_name eq $mutator_name ) {
62 2         3 my $accessor;
63 2 50 33     10 if ( $ra && $wa ) {
    0          
64 2         8 $accessor = $self->make_default( $field, $value );
65             }
66             elsif ($ra) {
67 0         0 $accessor = $self->make_ro_default( $field, $value );
68             }
69 2         4 my $fullname = "${class}::$accessor_name";
70 2         3 my $subnamed = 0;
71 2 50       14 subname( $fullname, $accessor ) if defined &subname;
72 2         3 $subnamed = 1;
73 2         3 *{$fullname} = $accessor;
  2         20  
74             }
75             else {
76 2         4 my $fullaccname = "${class}::$accessor_name";
77 2         4 my $fullmutname = "${class}::$mutator_name";
78 2 50 33     6 if ( $ra and not defined &{$fullaccname} ) {
  2         22  
79 2         9 my $accessor = $self->make_ro_default( $field, $value );
80 2 50       7 subname( $fullaccname, $accessor ) if defined &subname;
81 2         4 *{$fullaccname} = $accessor;
  2         9  
82             }
83 2 100 66     14 if ( $wa and not defined &{$fullmutname} ) {
  1         7  
84 1         9 my $mutator = $self->make_wo_accessor($field);
85 1 50       10 subname( $fullmutname, $mutator ) if defined &subname;
86 1         2 *{$fullmutname} = $mutator;
  1         12  
87             }
88             }
89             }
90             }
91              
92             sub make_default {
93 2     2 0 3 my ( $class, $field, $value ) = @_;
94             return sub {
95 4     4   2122 my $self = shift;
96              
97 4 100       29 if (@_) {
    100          
98 1         6 return $self->set( $field, @_ );
99             }
100             elsif ( ! defined $self->get($field) ) {
101 2         27 return $self->set( $field, $value );
102             }
103             else {
104 1         9 return $self->get($field);
105             }
106 2         18 };
107              
108             }
109              
110             sub make_ro_default {
111 2     2 0 4 my ( $class, $field, $value ) = @_;
112             return sub {
113 2     2   2649 my $self = shift;
114 2 50       16 if (@_) {
    50          
115 0         0 my $caller = caller;
116 0         0 $self->_croak(
117             "'$caller' cannot alter the value of '$field' on objects of class '$class'"
118             );
119             }
120             elsif ( ! defined $self->get($field) ) {
121 2         36 return $self->set( $field, $value );
122             }
123             else {
124 0           return $self->get($field);
125             }
126             }
127 2         11 }
128              
129             1;
130             __END__