File Coverage

lib/Class/Accessor/Fast/WithBuilder.pm
Criterion Covered Total %
statement 29 29 100.0
branch 12 14 85.7
condition n/a
subroutine 9 9 100.0
pod 3 3 100.0
total 53 55 96.3


line stmt bran cond sub pod time code
1             package Class::Accessor::Fast::WithBuilder;
2              
3             =head1 NAME
4              
5             Class::Accessor::Fast::WithBuilder - Class::Accessor::Fast with lazy defaults
6              
7             =head1 VERSION
8              
9             0.0101
10              
11             =head1 DESCRIPTION
12              
13             This module will require builders for each attribute defined. This means
14             that adding attributes with this module, is something like this code
15             from L:
16              
17             has age => (
18             is => "ro", # or rw
19             lazy => 1,
20             builder => "_build_age",
21             );
22              
23             NOTE: All builders will be called as late as possible.
24              
25             =head1 SYNOPSIS
26              
27             package Foo;
28             use base qw(Class::Accessor::Fast::WithBuilder);
29              
30             Foo->mk_accessors(qw( name age ));
31              
32             sub _build_name { $_[0]->_croak("'name' attribute cannot be built!") }
33             sub _build_age { 0 }
34              
35             print Foo->new->name; # BOOM!
36             print Foo->new->age; # Will print "0"
37             print Foo->new({ age => 123 })->age; # Will print "123"
38              
39             =cut
40              
41 1     1   41065 use strict;
  1         3  
  1         42  
42 1     1   6 use warnings;
  1         2  
  1         30  
43 1     1   5 use base 'Class::Accessor::Fast'; # overriding all ::Fast methods, but...
  1         3  
  1         1755  
44              
45             our $VERSION = '0.0101';
46              
47             =head1 METHODS
48              
49             =head2 make_accessor
50              
51             See L
52              
53             =cut
54              
55             sub make_accessor {
56 1     1 1 42 my($class, $field) = @_;
57 1         4 my $builder = "_build_$field";
58              
59             return sub {
60 3 50   3   924 return $_[0]->{$field} = @_ == 2 ? $_[1] : [@_[1..$#_]] if @_ > 1;
    100          
61 2 100       37 exists $_[0]->{$field} or $_[0]->{$field} = $_[0]->$builder;
62 2 50       16 return $_[0]->{$field} if @_ == 1;
63 1         7 };
64             }
65              
66             =head2 make_ro_accessor
67              
68             See L
69              
70             =cut
71              
72             sub make_ro_accessor {
73 1     1 1 28 my($class, $field) = @_;
74 1         3 my $builder = "_build_$field";
75              
76             return sub {
77 3 100   3   537 exists $_[0]->{$field} or $_[0]->{$field} = $_[0]->$builder;
78 3 100       23 return $_[0]->{$field} if @_ == 1;
79 1         3 my $caller = caller;
80 1         9 $_[0]->_croak("'$caller' cannot alter the value of '$field' on objects of class '$class'");
81 1         9 };
82             }
83              
84             =head2 make_wo_accessor
85              
86             This is not implemented. (See L)
87              
88             =cut
89              
90             sub make_wo_accessor {
91 1     1 1 677 $_[0]->_croak('not implemented');
92             }
93              
94             # used to check if _build_foo() methods are defined
95             sub _mk_accessors {
96 3     3   8829 my $class = shift;
97 3         8 my($type, @fields) = @_;
98              
99 3         5 for my $f (@fields) {
100 3 100       38 unless($class->can("_build_$f")) {
101 1         14 $class->_croak("$class\::_build_$f() is required!");
102             }
103             }
104              
105 2         17 return $class->SUPER::_mk_accessors(@_);
106             }
107              
108             =head1 COPYRIGHT & LICENSE
109              
110             =head1 AUTHOR
111              
112             Jan Henning Thorsen C<< jhthorsen at cpan.org >>
113              
114             =cut
115              
116             1;