File Coverage

blib/lib/Data/All/Base.pm
Criterion Covered Total %
statement 46 50 92.0
branch 15 22 68.1
condition n/a
subroutine 11 12 91.6
pod 0 5 0.0
total 72 89 80.9


line stmt bran cond sub pod time code
1             package Data::All::Base;
2              
3              
4 1     1   5 use strict;
  1         2  
  1         40  
5              
6              
7 1     1   844 use Symbol;
  1         878  
  1         65  
8              
9 1     1   6 use base 'Exporter';
  1         2  
  1         323  
10              
11             our @EXPORT = qw(new internal attribute populate error );
12              
13             our $VERSION = 1.0;
14              
15             sub internal;
16             internal 'ERROR' => [];
17              
18             sub error {
19 0     0 0 0 my $self = shift;
20 0 0       0 push (@{ $self->__ERROR() }, @_) if @_;
  0         0  
21 0         0 $self->__ERROR();
22             }
23              
24             sub new
25             # Bypass Spiffy's new, so we can call init()
26             {
27 9     9 0 458 my $class = shift;
28 9         37 my $self = bless Symbol::gensym(), $class;
29            
30 9 50       256 return ($self->can('init'))
31             ? $self->init(@_)
32             : $self;
33             }
34              
35              
36             sub attribute
37             # Creates an anonymous subroutine and places it in the caller's
38             # package (i.e. $self->name).
39             # Consider lvalue expression to allow $self->name = "newvalue".
40             # http://perl.active-venture.com/pod/perlsub.html
41             {
42 18     18 0 38 my $package = caller;
43 18         34 my ($attribute, $default) = @_;
44 1     1   6 no strict 'refs';
  1         1  
  1         195  
45 18 50       19 return if defined &{"${package}::$attribute"};
  18         118  
46 18         112 *{"${package}::$attribute"} =
47             sub {
48 156     156   202 my $self = shift;
49 156 100       427 unless (exists *$self->{$attribute}) {
50 40 50       127 *$self->{$attribute} =
    100          
51             ref($default) eq 'ARRAY' ? [] :
52             ref($default) eq 'HASH' ? {} :
53             $default;
54             }
55 156 100       796 return *$self->{$attribute} unless @_;
56 47         132 *$self->{$attribute} = shift;
57 18         81 };
58             }
59              
60             sub internal
61             # Used like attribute 'name' => 'val'. The difference being
62             # the internal attribute and it accessor are stored as '__name'
63             {
64 10     10 0 20 my $package = caller;
65 10         17 my ($attribute, $default) = @_;
66 10         21 $attribute = "__$attribute";
67 1     1   6 no strict 'refs';
  1         2  
  1         280  
68 10 50       13 return if defined &{"${package}::$attribute"};
  10         63  
69 10         74 *{"${package}::$attribute"} =
70             sub {
71 105     105   226 my $self = shift;
72 105 100       250 unless (exists *$self->{$attribute}) {
73 18         40 *$self->{$attribute} = $default;
74             }
75 105 100       1106 return *$self->{$attribute} unless @_;
76 20         62 *$self->{$attribute} = shift;
77 10         38 };
78             }
79              
80              
81             sub populate
82             # populate $self->ACCESSOR with arguments in $args.
83             # This is usually called by init() after the args have been parsed.
84             {
85 10     10 0 16 my ($self, $args) = @_;
86              
87 10         13 for my $a (keys %{ $args })
  10         42  
88             {
89 36 50       130 warn("No attribute method for $a"), next
90             unless $self->can($a);
91             #warn 9, "Running $a";
92 36         105 $self->$a($args->{$a});
93             }
94             }
95              
96              
97              
98              
99              
100              
101             1;