File Coverage

blib/lib/Text/StructuredBase.pm
Criterion Covered Total %
statement 26 49 53.0
branch 9 46 19.5
condition 1 3 33.3
subroutine 4 5 80.0
pod 1 1 100.0
total 41 104 39.4


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Text::StructuredBase - Structured text base class
4              
5             =head1 SYNOPSIS
6              
7             use base qw/Text::StructuredBase/;
8              
9             $object->debug($n);
10              
11             =head1 DESCRIPTION
12              
13             I acts as a base class for B.
14              
15             =cut
16              
17             package Text::StructuredBase;
18 1     1   5 use strict;
  1         7  
  1         32  
19 1     1   4 use vars qw($AUTOLOAD);
  1         2  
  1         34  
20 1     1   5 use Carp;
  1         1  
  1         752  
21              
22             ## CLASS DATA
23              
24             my $Debugging = 0;
25              
26             =head1 BASE CLASS METHODS
27              
28             =head2 AUTOLOAD()
29              
30             AUTOLOAD() provides default accessor methods (apart from DESTROY())
31             for any of its subclasses. For AUTOLOAD() to catch calls to these
32             methods objects must be implemented as an anonymous hash. Object
33             attributes must
34              
35             =over 4
36              
37             =item *) have UPPER CASE names
38              
39             =item *) have keys in attribute _PERMITTED (an anonymous hash)
40              
41             =back
42              
43             The name accessor method is the name of the attribute in B
44             case>. The 'set' versions of these accessor methods require a single
45             scalar argument (which could of course be a reference.) Both 'set'
46             and 'get' versions return the attribute's value.
47              
48             B
49              
50             =over 4
51              
52             =item B
53              
54             Attribute names matching the pattern B will be treated as
55             arrayrefs. These accessors require an arrayref as an argument. If
56             the attribute is defined they return the arrayref, otherwise they
57             return an empty arrayref.
58              
59             A method B<*_l_add(@foo)> can be called on this type of attribute to
60             add the elements in I<@foo> to the array. If the attribute is defined
61             they return the arrayref, otherwise they return an empty arrayref.
62              
63             =item B
64              
65             Attribute names matching the pattern B will be treated as
66             hashrefs. These accessors require a reference to an array containing
67             key/value pairs. If the attribute is defined they return the hashref,
68             otherwise they return an empty hashref.
69              
70             A method B<*_h_byname(@list)> can be called on this type of attribute.
71             These methods will return a list which is the hash slice of the B<_H>
72             attribute value over I<@list> or an empty list if the attribute is
73             undefined.
74              
75             A method B<*_h_add(\%foo)> can be called on this type of attribute to
76             add the elements in I<%foo> to the hash. If the attribute is defined
77             they return the hashref, otherwise they return an empty hashref.
78              
79             =back
80              
81             =cut
82              
83             sub AUTOLOAD {
84 6     6   14 my $self = shift;
85 6 50       17 my $type = ref($self) or die "$self is not an object";
86 6 50 33     34 warn "AUTOLOAD($AUTOLOAD)" if $self->{_DEBUG} || $Debugging;
87              
88 6         10 my $method = $AUTOLOAD;
89 6         29 $method =~ s/.*://; # strip fully-qualified portion
90              
91             # accessor methods
92 6         10 $method = uc($method);
93 6 50       15 return if ( $method eq 'DESTROY' ); # don't catch 'DESTROY'
94 6         8 my $name = $method;
95 6         17 $name =~ s/_H_BYNAME|_H_ADD$/_H/;
96 6         7 $name =~ s/_L_ADD$/_L/;
97 6 50       18 unless ( exists $self->{_PERMITTED}->{$name} ) {
98 0         0 die "Can't access `$name' field in class $type";
99             }
100              
101 6 0       15 print STDERR "\$_[0] = ",defined($_[0]) ? $_[0] : 'undef',"\n"
    50          
102             if $self->{_DEBUG};
103              
104 6 50       24 if ( $method =~ /_L$/ ) { # set/get array
    0          
    0          
    0          
    0          
105 6 100       15 @{$self->{$name}} = @{$_[0]} if $_[0];
  1         5  
  1         4  
106 6 50       40 return defined($self->{$name}) ? $self->{$name} : [];
107             } elsif ( $method =~ /_L_ADD$/ ) { # add to array
108 0 0         print STDERR "\@_ = @_\n" if $self->{_DEBUG};
109 0           push(@{$self->{$name}},@_);
  0            
110 0 0         return defined($self->{$name}) ? $self->{$name} : [];
111             } elsif ( $method =~ /_H$/ ) { # set/get hash
112 0 0         %{$self->{$name}} = @{$_[0]} if $_[0];
  0            
  0            
113 0 0         return defined($self->{$name}) ? $self->{$name} : {};
114             } elsif ( $method =~ /_H_ADD$/ ) { # add to hash
115 0           while ( my($k,$v) = each(%{$_[0]}) ) { $self->{$name}->{$k} = $v }
  0            
  0            
116 0 0         return defined($self->{$name}) ? $self->{$name} : {};
117             } elsif ( $method =~ /_H_BYNAME$/ ) { # get hash values by name
118 0 0         print STDERR "$self $name byname: @_\n" if $self->{_DEBUG};
119 0 0         return defined($self->{$name}) ? @{$self->{$name}}{@_} : ();
  0            
120             }
121             else { # set/get scalar
122 0 0         return @_ ? $self->{$name} = shift : $self->{$name};
123             }
124             }
125              
126             #------------------------------------------------------------------------------
127              
128             =head2 debug($n)
129              
130             As a class method sets the class attribute I<$Debugging> to I<$n>. As
131             an object method sets the object attribute I<$_DEBUG> to I<$n>.
132              
133             =cut
134              
135             sub debug {
136 0     0 1   my $self = shift;
137 0 0         confess "usage: thing->debug(level)" unless @_ == 1;
138 0           my $level = shift;
139 0 0         if (ref($self)) {
140 0           $self->{"_DEBUG"} = $level; # just myself
141             } else {
142 0           $Debugging = $level; # whole class
143             }
144             }
145              
146              
147             1;
148              
149             =head1 AUTHOR
150              
151             Paul Sharpe Epaul@miraclefish.comE
152              
153             =head1 COPYRIGHT
154              
155             Copyright (c) 1999 Paul Sharpe. England. All rights reserved. This
156             program is free software; you can redistribute it and/or modify it
157             under the same terms as Perl itself.
158              
159             =cut