File Coverage

blib/lib/Class/ObjectTemplate/DB.pm
Criterion Covered Total %
statement 177 205 86.3
branch 54 92 58.7
condition 5 9 55.5
subroutine 30 33 90.9
pod 1 13 7.6
total 267 352 75.8


line stmt bran cond sub pod time code
1             package Class::ObjectTemplate::DB;
2 1     1   893 use Class::ObjectTemplate 0.5;
  1         1598  
  1         61  
3 1     1   9 use Carp;
  1         2  
  1         63  
4 1     1   4 use strict;
  1         2  
  1         29  
5 1     1   4 no strict 'refs';
  1         2  
  1         35  
6             require Exporter;
7              
8 1     1   5 use vars qw(@ISA @EXPORT $VERSION $DEBUG);
  1         2  
  1         900  
9              
10             @ISA = qw(Class::ObjectTemplate Exporter);
11             @EXPORT = qw(attributes);
12             $VERSION = 0.27;
13              
14             $DEBUG = 0; # assign 1 to it to see code generated on the fly
15              
16             # JES -- Added to be able to turn automatic lookup on and off at
17             # method definition time. Set this to be true before calling
18             # attributes and the getter method will call undefined() if the
19             # current value is 'undef'.
20              
21             # Create accessor functions, and new()
22             #
23             # attributes(lookup => ['foo', 'bar'], no_lookup => ['baz'])
24             # attributes('foo', 'bar', 'baz')
25             #
26             sub attributes {
27 7     7   23 my ($pkg) = caller;
28              
29 7         43 croak "Error: attributes() invoked multiple times"
30 7 50       13 if scalar @{"${pkg}::_ATTRIBUTES_"};
31              
32 7         13 my %args;
33             # figure out if we were called with a simple parameter list
34             # or with a hash-style parameter list
35 7 100       20 if (scalar @_) {
36 6 100 66     151 if (scalar @_ % 2 == 0 &&
      66        
      33        
37             ($_[0] eq 'lookup' || $_[0] eq 'no_lookup') &&
38             ref($_[1]) eq 'ARRAY') {
39             # we were called with hash style parameters
40 5         22 %args = @_;
41             } else {
42             # we were called with a simple parameter list
43 1         5 %args = ('no_lookup' => [@_]);
44             }
45             }
46 7         13 my $lookup;
47              
48             #
49             # We must define a constructor for the class, because we must
50             # declare the variables used for the free list, $_max_id and
51             # @_free. If we don't, we will get compile errors for any class
52             # that declares itself a subclass of any Class::ObjectTemplate
53             # class
54             #
55 7 50       18 print STDERR "defining constructor for $pkg\n" if $DEBUG;
56 7         27 my $code .= Class::ObjectTemplate::_define_constructor($pkg);
57              
58 7 50       182 print STDERR "Creating methods for $pkg\n" if $DEBUG;
59 7         21 foreach my $key (keys %args) {
60 8         11 push(@{"${pkg}::_ATTRIBUTES_"},@{$args{$key}});
  8         22  
  8         108  
61              
62             # set up the $lookup boolean
63 8         20 $lookup = ($key eq 'lookup');
64 8         11 foreach my $attr (@{$args{$key}}) {
  8         23  
65 12 50       123 print STDERR " defining method $attr\n" if $DEBUG;
66              
67             # If a field name is "color", create a global list in the
68             # calling package called @_color
69 12         105 @{"${pkg}::_$attr"} = ();
  12         65  
70              
71             # If the accessor is already present, give a warning
72 12 100       122 if (UNIVERSAL::can($pkg,"$attr")) {
73 1         261 carp "$pkg already has method: $attr";
74             } else {
75 11         26 $code .= _define_accessor ($pkg, $attr, $lookup);
76             }
77             }
78             }
79              
80 1 0   1 0 7 eval $code;
  1 0   1 0 1  
  1 50   1 0 395  
  1 50   1 0 7  
  1 50   1 0 2  
  1 50   1 0 365  
  1 50   1 0 6  
  1 50   0 0 2  
  1 50   1 0 283  
  1 50   1 0 6  
  1 50   1 0 2  
  1 100   3 0 410  
  1 50   1   14  
  1 50   1   2  
  1 50   2   272  
  1 50   10   7  
  1 50   2   2  
  1 50   1   356  
  1 50   2   7  
  1 50   0   2  
  1 50   1   493  
  7 50   2   618  
  0 50   3   0  
  0 100   2   0  
  0 100   2   0  
  0 50       0  
  0 100       0  
  0 50       0  
  0 0       0  
  0 50       0  
  1 50       44  
  1 100       2  
  1 100       4  
  0 50       0  
  1 50       2  
  1 100       3  
  1 50       12  
  1         37  
  1         31  
  1         3  
  1         2  
  1         3  
  1         3  
  0         0  
  1         2  
  1         2  
  1         5  
  1         9  
  1         33  
  1         3  
  1         43  
  1         2  
  1         8  
  0         0  
  1         3  
  1         3  
  1         7  
  1         10  
  1         38  
  1         3  
  3         113  
  3         37  
  3         11  
  1         2  
  2         3  
  3         9  
  3         8  
  3         13  
  3         96  
  3         10  
  1         3  
  1         2  
  1         5  
  0         0  
  1         2  
  1         2  
  1         4  
  1         8  
  1         36  
  1         4  
  1         36  
  1         2  
  1         4  
  0         0  
  1         3  
  1         4  
  1         4  
  1         10  
  1         32  
  1         4  
  2         38  
  2         3  
  2         6  
  0         0  
  2         4  
  2         5  
  2         7  
  2         11  
  2         63  
  2         7  
  10         181  
  10         34  
  4         20  
  6         37  
  2         77  
  2         8  
  1         9  
  1         6  
  1         30  
  1         4  
  0         0  
  1         11  
  2         105  
  2         10  
  1         5  
  1         3  
  0         0  
  1         9  
  1         4  
  1         5  
  0         0  
  0         0  
  0         0  
  0         0  
  1         3  
  1         3  
  0         0  
  1         3  
  0         0  
  1         3  
  1         4  
  1         5  
  2         5  
  2         8  
  1         3  
  1         4  
  3         8  
  3         12  
  1         4  
  2         9  
  2         7  
  2         7  
  0         0  
  2         7  
  0         0  
  2         7  
  2         11  
  2         10  
  2         49  
  2         7  
  1         4  
  1         3  
  1         5  
  1         5  
  0         0  
  0         0  
81 7 50       44 if ($@) {
82 0         0 die "ERROR defining constructor and attributes for '$pkg':\n"
83             . "\t$@\n"
84             . "-----------------------------------------------------"
85             . $code;
86             }
87             }
88              
89             sub _define_accessor {
90 11     11   23 my ($pkg, $attr, $lookup) = @_;
91              
92             # This code creates an accessor method for a given
93             # attribute name. This method returns the attribute value
94             # if given no args, and modifies it if given one arg.
95             # Either way, it returns the latest value of that attribute
96              
97             # in ObjectTemplate::DB, if the getter is called and the current
98             # value of the attribute is undef, then the classes undefined()
99             # method will be invoked with the name of the attribute.
100              
101 11         13 my $code;
102 11 100       24 if ($lookup) {
103             # If we are to do automatic lookup when the current value
104             # is undefined, we need to be complicated
105 5         21 $code = <<"CODE";
106             package $pkg;
107             sub $attr { # Accessor ...
108             my \$name = ref(\$_[0]) . "::_$attr";
109             return \$name->[\${\$_[0]}] = \$_[1] if \@_ > 1; # set
110             return \$name->[\${\$_[0]}]
111             if defined \$name->[\${\$_[0]}]; # get
112             # else call undefined(), and give it a change to define
113             return \$name->[\${\$_[0]}] = \$_[0]->undefined('$attr');
114             }
115             CODE
116             } else {
117             # if we don't need to do lookup, it's short and sweet
118 6         20 $code = <<"CODE";
119             package $pkg;
120             sub $attr { # Accessor ...
121             my \$name = ref(\$_[0]) . "::_$attr";
122             \@_ > 1 ? \$name->[\${\$_[0]}] = \$_[1] # set
123             : \$name->[\${\$_[0]}]; # get
124             }
125             CODE
126             }
127 11         64 return $code;
128             }
129              
130             # JES
131             # default function for lookup. Does the obvious
132 0     0 1   sub undefined {return undef;}
133             1;
134              
135             __END__