File Coverage

blib/lib/Class/Accessor/Lite/Lazy.pm
Criterion Covered Total %
statement 58 64 90.6
branch 21 24 87.5
condition n/a
subroutine 15 16 93.7
pod 2 2 100.0
total 96 106 90.5


line stmt bran cond sub pod time code
1             package Class::Accessor::Lite::Lazy;
2 3     3   48309 use strict;
  3         9  
  3         114  
3 3     3   15 use warnings;
  3         6  
  3         85  
4 3     3   78 use 5.008_001;
  3         11  
  3         135  
5 3     3   2942 use parent 'Class::Accessor::Lite';
  3         1207  
  3         333  
6 3     3   8585 use Carp ();
  3         7  
  3         1236  
7              
8             our $VERSION = '0.03';
9              
10             my %key_ctor = (
11             ro_lazy => \&_mk_ro_lazy_accessors,
12             rw_lazy => \&_mk_lazy_accessors,
13             );
14              
15             sub import {
16 4     4   257 my ($class, %args) = @_;
17 4         11 my $pkg = caller;
18 4         108 foreach my $key (sort keys %key_ctor) {
19 8 100       52 if (defined (my $value = delete $args{$key})) {
20 3 50       18 Carp::croak "value of the '$key' parameter should be an arrayref or hashref"
21             unless ref($value) =~ /^(ARRAY|HASH)$/;
22 3 100       10 $value = [ $value ] if ref $value eq 'HASH';
23 3         8 $key_ctor{$key}->($pkg, @$value);
24             }
25             }
26 4         16 @_ = ($class, %args);
27 4         23 goto \&Class::Accessor::Lite::import;
28             }
29              
30             sub mk_lazy_accessors {
31 1     1 1 46 (undef, my @properties) = @_;
32 1         2 my $pkg = caller;
33 1         4 _mk_lazy_accessors($pkg, @properties);
34             }
35              
36             sub mk_ro_lazy_accessors {
37 0     0 1 0 (undef, my @properties) = @_;
38 0         0 my $pkg = caller;
39 0         0 _mk_ro_lazy_accessors($pkg, @properties);
40             }
41              
42             sub _mk_ro_lazy_accessors {
43 2     2   3 my $pkg = shift;
44 2 100       3 my %decls = map { ref $_ eq 'HASH' ? ( %$_ ) : ( $_ => undef ) } @_;
  3         16  
45 3     3   17 no strict 'refs';
  3         10  
  3         1326  
46 2         10 while (my ($name, $builder) = each %decls) {
47 4         9 *{"$pkg\::$name"} = __m_ro_lazy($pkg, $name, $builder);
  4         37  
48             }
49             }
50              
51             sub _mk_lazy_accessors {
52 2     2   4 my $pkg = shift;
53 2 100       5 my %decls = map { ref $_ eq 'HASH' ? ( %$_ ) : ( $_ => undef ) } @_;
  4         19  
54 3     3   19 no strict 'refs';
  3         5  
  3         1525  
55 2         10 while (my ($name, $builder) = each %decls) {
56 4         13 *{"$pkg\::$name"} = __m_lazy($name, $builder);
  4         28  
57             }
58             }
59              
60             sub __m_ro_lazy {
61 4     4   5 my ($pkg, $name, $builder) = @_;
62 4 100       8 $builder = "_build_$name" unless defined $builder;
63             return sub {
64 5 50   5   7432 if (@_ == 1) {
65 5 100       28 return $_[0]->{$name} if exists $_[0]->{$name};
66 4         19 return $_[0]->{$name} = $_[0]->$builder;
67             } else {
68 0         0 my $caller = caller(0);
69 0         0 Carp::croak("'$caller' cannot access the value of '$name' on objects of class '$pkg'");
70             }
71 4         20 };
72             }
73              
74             sub __m_lazy {
75 4     4   6 my ($name, $builder) = @_;
76 4 100       14 $builder = "_build_$name" unless defined $builder;
77             return sub {
78 10 100   10   4148 if (@_ == 1) {
    50          
79 8 100       42 return $_[0]->{$name} if exists $_[0]->{$name};
80 4         33 return $_[0]->{$name} = $_[0]->$builder;
81             } elsif (@_ == 2) {
82 2         9 return $_[0]->{$name} = $_[1];
83             } else {
84 0           return shift->{$name} = \@_;
85             }
86 4         14 };
87             }
88              
89             1;
90              
91             __END__