File Coverage

blib/lib/Class/Struct/FIELDS.pm
Criterion Covered Total %
statement 449 466 96.3
branch 84 144 58.3
condition 15 78 19.2
subroutine 130 130 100.0
pod 1 2 50.0
total 679 820 82.8


line stmt bran cond sub pod time code
1             package Class::Struct::FIELDS;
2              
3             require 5.005_64;
4 6     6   83316 use strict;
  6         16  
  6         298  
5 6     6   32 use warnings::register;
  6         10  
  6         1395  
6              
7 5     5   29 use Carp;
  5         14  
  5         362  
8              
9             # AutoLoader would be nice, but it mucks up with evaling the package
10             # definitions in 'struct'. Hmmm.
11              
12 5     5   5212 use AutoLoader qw(AUTOLOAD);
  5         9525  
  5         31  
13 5     5   180 use base qw(Exporter);
  5         9  
  5         4347  
14              
15             # Items to export into callers namespace by default. Note: do not
16             # export names by default without a very good reason. Use EXPORT_OK
17             # instead. Do not simply export all your public
18             # functions/methods/constants.
19              
20             # This allows declaration use Class::Struct::FIELDS ':all'; If you do
21             # not need this, moving things directly into @EXPORT or @EXPORT_OK
22             # will save memory.
23              
24             our %EXPORT_TAGS = (all => [qw(struct)]);
25             our @EXPORT_OK = (@{$EXPORT_TAGS{all}});
26             our @EXPORT = qw(struct);
27              
28             # I'd like to say "our $VERSION = v1.1;", but MakeMaker--even in perl
29             # 5.6.0--, doesn't grok that and has trouble creating a Makefile.
30             our $VERSION = '1.1';
31             my $rcs = qq$Id: FIELDS.pm,v 1.1.1.1 2001/04/08 23:28:31 binkley Exp $;
32              
33             # my %SEEN_PKGS = ();
34              
35             sub struct;
36              
37             sub _array ($$;$);
38             sub _arraytie ($$);
39             sub _arrayref ($$;$);
40             sub _code ($$;$);
41             sub _coderef ($$;$);
42             sub _baseclass_warning ($$);
43             sub _get_isa ($$);
44             sub _hash ($$;$);
45             sub _hashtie ($$);
46             sub _hashref ($$;$);
47             sub _mini_prolog ($$);
48             sub _new_new_warning ($);
49             sub _object ($$$$;$);
50             sub _array_object ($$$$;$);
51             sub _hash_object ($$$$;$);
52             sub _objectref ($$$$;$);
53             sub _override_warning ($$);
54             sub _postlog ( );
55             sub _prolog ($$$);
56             sub _regexp ($$;$);
57             sub _regexpref ($$;$);
58             sub _scalar ($$;$);
59             sub _scalarref ($$;$);
60             sub _stringify ( );
61             sub _usage_error;
62              
63             # Preloaded methods go here.
64              
65             sub import {
66 39     39   718 my ($class) = shift;
67              
68             # We consume all of @_, so don't pass it along.
69 39         3123 $class->export_to_level (1);
70              
71             # Consume our own frame so that &struct thinks our caller is the
72             # real caller.
73 39 100       5436 goto &struct if @_;
74             }
75              
76             sub struct {
77 29     29 1 66 my ($class, $isa, $decls);
78 29         56 my $caller = caller;
79              
80 29 100       93 if (my $ref = ref $_[0]) { # guess class from caller
81 4 100       14 if ($ref eq 'ARRAY') {
    50          
82 3 100       8 if ($ref = ref $_[1]) {
83 1 50       4 if ($ref eq 'HASH') { # called as "{LIST}, [LIST]"
84 1         3 ($class, $isa, $decls) = ($caller, shift, shift);
85 1 50       5 _usage_error if @_;
86             }
87              
88             else {
89 0         0 _usage_error;
90             }
91             }
92              
93             else { # called as "[LIST], LIST"
94 2         9 ($class, $isa, $decls) = ($caller, shift, {@_});
95             }
96             }
97              
98             elsif ($ref eq 'HASH') { # called as "{LIST}"
99 1         3 ($class, $isa, $decls) = ($caller, [], shift);
100 1 50       5 _usage_error if @_;
101             }
102              
103             else {
104 0         0 _usage_error;
105             }
106             }
107              
108             else { # caller listed
109 25 100       82 if ($ref = ref $_[1]) {
110 19 100       68 if ($ref eq 'ARRAY') {
    50          
111 11 100       33 if ($ref = ref $_[2]) {
112 2 50       8 if ($ref eq 'HASH') { # called as "[LIST], {LIST}"
113 2         4 ($class, $isa, $decls) = (shift, shift, shift);
114 2 50       9 _usage_error if @_;
115             }
116              
117             else {
118 0         0 _usage_error;
119             }
120             }
121              
122             else { # called as "[LIST], LIST"
123 9         35 ($class, $isa, $decls) = (shift, shift, {@_});
124             }
125             }
126              
127             elsif ($ref eq 'HASH') { # called as "CLASS, {LIST}"
128 8         26 ($class, $isa, $decls) = (shift, [], shift);
129 8 50       42 _usage_error if @_;
130             }
131              
132             else {
133 0         0 _usage_error;
134             }
135             }
136              
137             else {
138 6 50       21 if (@_) {
139 6 50       23 if (@_ % 2) { # called as "LIST" with CLASS
140 6         33 ($class, $isa, $decls) = (shift, [], {@_});
141             }
142              
143             else { # called as "LIST" without CLASS
144 0         0 ($class, $isa, $decls) = ($caller, [], {});
145             }
146             }
147              
148             else { # called as plain "&struct"
149 0         0 ($class, $isa, $decls) = ($caller, [], {});
150             }
151             }
152             }
153              
154 29     16   87 eval _mini_prolog ($class, $isa); # baseclass warnings
  16     4   232  
  18     2   2405  
  18     2   3734  
  4     2   56  
  4     2   7  
  4     2   36  
  2     2   18  
  2     2   4  
  2     2   19  
  2     2   10  
  2     2   2  
  2     2   458  
  2     1   11  
  2         3  
  2         627  
  2         11  
  2         3  
  2         18  
  2         11  
  2         8  
  2         472  
  2         12  
  2         6  
  2         808  
  2         17  
  2         4  
  2         25  
  2         11  
  2         3  
  2         489  
  2         11  
  2         4  
  2         18  
  2         10  
  2         4  
  2         509  
  2         10  
  2         83  
  2         577  
  1         5  
  1         2  
  1         14  
155 29         88 my $eval = _prolog ($class, $isa, $decls);
156              
157             # Automagic overload support.
158             $eval .= _stringify
159 5 100   5   38 if (do { no strict qw(refs); exists &{"$class\::as_string"} });
  5         12  
  5         494  
  29         185  
  29         36  
  29         149  
160              
161 29         118 while (my ($k, $v) = each %$decls) {
162 29         44 my $hidden = undef;
163              
164             # Don't make subroutines for "private" keys; you should access
165             # them directly: $self->{_blah_blah}; See fields.
166 29 50       77 next if $k =~ /^_/o;
167              
168             # Check for three cases:
169             #
170             # 1. Caller has already defined an accessor.
171             #
172             # 2. Base class has a same-named method.
173             #
174             # 3. Take care to use exists instead of defined so that caller can
175             # use sub declarations before actually defining the access
176             # method.
177              
178 5 100   5   30 if (do { no strict qw(refs); exists &{"$class\::$k"} }) {
  5         7  
  5         4465  
  29         37  
  29         27  
  29         124  
179 3         71 _override_warning ($class, $k);
180 3         9 $hidden = 1;
181             # next;
182             }
183              
184             # This doesn't work? XXX
185 29 100       377 _baseclass_warning ($class, $k) if UNIVERSAL::can ($class, $k);
186              
187 29 100 66     444 if ($v eq '$') {
    100 66        
    100 66        
    100 66        
    100 66        
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
    50          
188 11         322 $eval .= _scalar ($class, $k, $hidden);
189             }
190              
191             elsif ($v eq '\$' or $v eq '*$') {
192 1         5 $eval .= _scalarref ($class, $k, $hidden);
193             }
194              
195             elsif ($v eq '@') {
196 1         7 $eval .= _array ($class, $k, $hidden);
197             }
198              
199             # EXPERIMENTAL XXX
200             elsif ($v eq '+@') {
201 1         9 $eval .= _arraytie ($class, $k);
202 1         8 $eval .= _array ($class, $k, $hidden);
203             }
204              
205             elsif ($v eq '\@' or $v eq '*@') {
206 1         5 $eval .= _arrayref ($class, $k, $hidden);
207             }
208              
209             elsif ($v eq '%') {
210 2         12 $eval .= _hash ($class, $k, $hidden);
211             }
212              
213             # EXPERIMENTAL XXX
214             elsif ($v eq '+%') {
215 1         7 $eval .= _hashtie ($class, $k);
216 1         25 $eval .= _hash ($class, $k, $hidden);
217             }
218              
219             elsif ($v eq '\%' or $v eq '*%') {
220 1         5 $eval .= _hashref ($class, $k, $hidden);
221             }
222              
223             elsif ($v eq '&') {
224 1         5 $eval .= _code ($class, $k, $hidden);
225             }
226              
227             elsif ($v eq '\&' or $v eq '*&') {
228 1         7 $eval .= _coderef ($class, $k, $hidden);
229             }
230              
231             elsif ($v eq '/') {
232 1         4 $eval .= _regexp ($class, $k, $hidden);
233             }
234              
235             elsif ($v eq '\/' or $v eq '*/') {
236 1         5 $eval .= _regexpref ($class, $k, $hidden);
237             }
238              
239             # EXPERIMENTAL XXX
240             elsif ($v =~ s/^\+@(\w+(?:::\w+)*)$/$1/o) {
241             # $SEEN_PKGS{$class}->{$k} = $v;
242 1         39 $eval .= _arraytie ($class, $k);
243 1         11 $eval .= _array_object ($class, $caller, $k, $v, $hidden);
244             }
245              
246             # EXPERIMENTAL XXX
247             elsif ($v =~ s/^@(\w+(?:::\w+)*)$/$1/o) {
248             # $SEEN_PKGS{$class}->{$k} = $v;
249 0         0 $eval .= _array_object ($class, $caller, $k, $v, $hidden);
250             }
251              
252             # EXPERIMENTAL XXX
253             elsif ($v =~ s/^\+%(\w+(?:::\w+)*)$/$1/o) {
254             # $SEEN_PKGS{$class}->{$k} = $v;
255 1         34 $eval .= _hashtie ($class, $k);
256 1         8 $eval .= _hash_object ($class, $caller, $k, $v, $hidden);
257             }
258              
259             # EXPERIMENTAL XXX
260             elsif ($v =~ s/^%(\w+(?:::\w+)*)$/$1/o) {
261             # $SEEN_PKGS{$class}->{$k} = $v;
262 0         0 $eval .= _hash_object ($class, $caller, $k, $v, $hidden);
263             }
264              
265             elsif ($v =~ s/^[\\*](\w+(?:::\w+)*)$/$1/o) {
266             # $SEEN_PKGS{$class}->{$k} = $v;
267 1         7 $eval .= _objectref ($class, $caller, $k, $v, $hidden);
268             }
269              
270             elsif ($v =~ /^\w+(?:::\w+)*$/o) {
271             # $SEEN_PKGS{$class}->{$k} = $v;
272 3         44 $eval .= _object ($class, $caller, $k, $v, $hidden);
273             }
274              
275             else {
276 0         0 _usage_error;
277             }
278             }
279              
280 29         70 $eval .= _postlog;
281              
282 29 100 33 8   2288 eval $eval;
  5 100 66 9   52  
  5 50 33 7   11  
  5 50 0 7   135  
  6 50 0 7   123  
  6 50 0 5   15  
  6 50 0 5   158  
  7 50 0 4   113  
  7 50 0 6   53  
  5 50 0 5   333  
  7 100 0 4   91  
  7 50 0 3   18  
  7 50 0 3   105  
  7 50 0 3   4998  
  7 50 0 2   9881  
  5 50 0 2   97  
  5 0 0 2   246  
  5 0 0 2   10  
  5 0 0 2   815  
  5 0 0 2   55  
  5 0 0 2   10  
  5 0   2   625  
  4 0   2   83  
  4 0   2   9  
  4 0   2   109  
  9 0   2   99  
  9 0   2   23  
  9 0   2   293  
  6 0   2   79  
  6     2   52  
  5     2   315  
  8     2   1001  
  5     2   142  
  5     2   107  
  5     2   43  
  4     2   37  
  4     2   50  
  4     2   429  
  4     2   22  
  4     2   807  
  3     2   17  
  3     2   5  
  3     2   1916  
  2     2   11  
  2     2   10  
  2     2   67  
  2     2   10  
  2     2   4  
  2     2   58  
  2     2   9  
  3     2   7  
  3     2   134  
  3     2   12  
  2     2   4  
  2     2   38  
  2     2   10  
  3     2   139  
  2     2   47  
  2     2   10  
  2     2   8  
  2     2   395  
  2     2   9  
  2     2   4  
  2     2   206  
  2     2   10  
  2     2   2  
  2     2   53  
  2     2   9  
  2     2   4  
  2     2   51  
  2     2   7  
  2     2   3  
  2     2   122  
  2     2   10  
  2     2   3  
  2     2   55  
  2     2   10  
  2     3   4  
  2     3   98  
  2     3   10  
  2     3   50  
  2     3   396  
  2     3   10  
  2     3   4  
  2     3   191  
  2     3   10  
  2     3   3  
  2     3   63  
  2     3   9  
  2     3   15  
  2     3   51  
  2     2   51  
  2     2   11  
  2     2   122  
  2     2   10  
  2     2   3  
  2     2   162  
  2     2   10  
  2         2  
  2         33  
  2         79  
  2         3  
  2         888  
  2         11  
  2         8  
  2         387  
  2         12  
  2         4  
  2         67  
  2         9  
  2         4  
  2         56  
  2         10  
  2         8  
  2         126  
  2         10  
  2         7  
  2         45  
  2         10  
  2         4  
  2         12  
  2         183  
  2         3  
  2         407  
  2         15  
  2         4  
  2         316  
  2         11  
  2         4  
  2         51  
  2         10  
  2         4  
  2         60  
  2         9  
  2         3  
  2         102  
  2         9  
  2         4  
  2         57  
  2         8  
  2         4  
  2         7  
  2         188  
  2         3  
  2         382  
  2         9  
  2         9  
  2         825  
  2         12  
  2         3  
  2         66  
  2         10  
  2         4  
  2         49  
  2         9  
  2         2  
  2         195  
  2         18  
  2         5  
  2         121  
  2         12  
  2         9  
  2         11  
  2         193  
  2         3  
  2         444  
  2         12  
  2         4  
  2         696  
  2         9  
  2         5  
  2         965  
  2         1442  
  2         4  
  2         155  
  2         9  
  2         102  
  2         220  
  2         10  
  2         4  
  2         160  
  2         10  
  2         5  
  2         166  
  2         12  
  2         3  
  2         376  
  2         12  
  2         5  
  2         475  
  2         12  
  2         4  
  2         69  
  2         13  
  2         4  
  2         75  
  2         11  
  2         6  
  2         205  
  2         10  
  2         4  
  2         62  
  2         10  
  2         5  
  2         33  
  2         117  
  2         3  
  2         1540  
  2         15  
  2         4  
  2         350  
  2         11  
  2         2  
  2         144  
  2         11  
  2         3  
  2         142  
  2         16  
  2         4  
  2         169  
  2         8  
  2         4  
  2         130  
  2         10  
  2         2  
  2         166  
  2         97  
  2         4  
  2         327  
  2         10  
  2         3  
  2         482  
  3         16  
  3         5  
  3         95  
  3         15  
  3         5  
  3         84  
  3         14  
  3         5  
  3         196  
  3         14  
  3         5  
  3         71  
  3         14  
  3         4  
  3         48  
  3         209  
  3         7  
  3         623  
  3         16  
  3         5  
  3         482  
  3         2092  
  3         1027  
  3         145  
  3         14  
  3         5  
  3         211  
  3         14  
  3         1287  
  3         295  
  3         14  
  3         7  
  3         196  
  3         13  
  3         6  
  3         161  
  3         98  
  3         5  
  3         330  
  3         172  
  3         4  
  3         659  
  2         10  
  2         2  
  2         130  
  2         10  
  2         4  
  2         943  
  2         1091  
  2         5  
  2         168  
  2         12  
  2         3  
  2         180  
  2         9  
  2         4  
  2         174  
  2         89  
  2         2  
  2         330  
  2         11  
  2         3  
  2         302  
283 29 50       412 carp $@ if $@;
284              
285 29         15840 $class;
286             }
287              
288             # Work around a broken UNIVERSAL::isa in 5.6.0:
289             if ($^V eq v5.6.0) {
290 5     5   32 no warnings;
  5         10  
  5         590  
291              
292             # sub UNIVERSAL::isa {
293             sub isa {
294 3     3 0 336 my ($class, $super) = @_;
295 3   33     30 $class = ref $class || $class;
296 3 0       16 return 1 if $class eq $super; # trivial case
297              
298             my $f = sub {
299 5     5   32 no strict qw(refs);
  5         8  
  5         1043  
300              
301 0     3   0 my ($class, $super, $g) = @_;
302 0         0 my @supers = @{"$class\::ISA"};
  0         0  
303              
304 0         0 foreach my $s (@supers) {
305 0 0       0 return 1 if $s eq $super;
306             # Does Perl optimizer understand tail recursion?
307 0         0 return $g->($s, $super, $g);
308             }
309              
310 0         0 return '';
311 3         25140 };
312              
313 0         0 return $f->($class, $super, $f);
314             }
315              
316             *UNIVERSAL::isa = \&isa;
317             }
318              
319             sub _get_isa ($$) {
320 58     58   93 my ($class, $isa) = @_;
321 58         64 my @isa;
322              
323             {
324 5     5   27 no strict qw(refs);
  5         10  
  5         1874  
  58         61  
325              
326 58         71 @isa = (@{"$class\::ISA"}, @$isa); # preserve the existing @ISA
  58         335  
327             }
328              
329 58         160 return @isa;
330             }
331              
332             sub _mini_prolog ($$) {
333 29     30   49 my ($class, $isa) = @_;
334 29         74 my @isa = _get_isa ($class, $isa);
335              
336 29         4133 <
337             {
338             package $class;
339             use base qw(@isa);
340             }
341             EOC
342             }
343              
344             sub _prolog ($$$) {
345 30     29   157 my ($class, $isa, $decls) = @_;
346 30         69 my @isa = _get_isa ($class, $isa);
347 30         380 my @fields = keys %$decls;
348              
349 30         3980 <
350             {
351             package $class;
352              
353             require 5.005_64;
354             use strict;
355             use warnings;
356              
357             use Carp;
358              
359             use base qw(@isa);
360             use fields qw(@fields);
361              
362             # Allow user to provide their own new as long as they return
363             # \$self->_init (\@_);
364             unless (do { no strict qw(refs); exists &{$class\::new} }) {
365             *{$class\::new} = sub {
366             my \$this = shift;
367             my \$class = ref \$this || \$this || __PACKAGE__;
368             my $class \$self = fields::new (\$class);
369              
370             \$self->_init (\@_);
371             };
372             }
373              
374             else {
375             Class::Struct::FIELDS::_new_new_warning ('$class');
376             }
377              
378             # Two-step initialization so that user-defined init's will have the
379             # parents' fields all ready to go. This relies on cooperation from
380             # sub new.
381             sub _init {
382             my $class \$self = shift;
383             my \%init = \@_;
384              
385             # Simple solution for now. Some problems:
386             #
387             # 1. Diamond inheritance can call _init multiple times. I don't
388             # know if it's a good thing, or a bad thing, but fields forbids
389             # multiple inheritance.
390             #
391             # 2. Member initialization gets called every time through.
392              
393             for (qw(@isa)) {
394             eval { bless \$self, \$_; \$self = \$self->_init (\@_) };
395             }
396              
397             bless \$self, qw($class);
398              
399             # Init our fields to be like Class::Struct. According to the
400             # documentation for fields, the call to fields::new should have
401             # set up our parents as well, so that we can init their fields
402             # too. Make sure to call the accessors so that user-defined ones
403             # are invoked (instead of assigning directly to the pseudo-hash.)
404             {
405             no strict qw(refs);
406              
407             # Only invoke valid keys; pass the rest through unmolested.
408             my \$c;
409              
410             while (my (\$k, \$v) = each \%init) {
411             \$self->\$c (\$v) if \$c = $class\::->can (\$k);
412             }
413             }
414              
415             eval { \$self = \$self->init (\@_) }; # if \$self->can ('init');
416              
417             \$self;
418             }
419             EOC
420             }
421              
422             sub _postlog ( ) {
423 29     29   69 <
424              
425             1;
426             }
427             EOC
428             }
429              
430             1;
431              
432             # Autoload methods go after __END__, and are processed by the
433             # autosplit program.
434              
435             __END__