File Coverage

blib/lib/Time/Frame.pm
Criterion Covered Total %
statement 51 202 25.2
branch 0 74 0.0
condition 0 37 0.0
subroutine 17 26 65.3
pod 2 2 100.0
total 70 341 20.5


line stmt bran cond sub pod time code
1             # 37VG26k - Time::Frame.pm created by Pip@CPAN.Org to make simple
2             # objects for frames of time.
3             # Desc: Frame describes a simple object which encapsulates 10 fields:
4             # Century, Year, Month, Day, hour, minute, second, frame, jink, zone
5             # where frame is normally 1/60th-of-a-second && jink is normally
6             # 1/60th-of-a-frame. The objects describe a high-precision time-frame
7             # (as in, a duration, a period, a length or span of time). Frame
8             # objects can be added to / subtracted from Time::PT objects to yield
9             # new specific PT instants.
10             # 1st: '0A1B2C3'
11             # 2nd: 'Yd:2003,j:A7_,M:a3I' or 'f:3aL9.eP'
12             # if field name ends with d, value is read as decimal nstd of default b64.
13             # Third way is super verbose decimal strings:
14             # '15 years, 3 months, 7 weeks, 4 jinx' can use any (or none) sep but :
15             # 4th is hash
16             # Total Jinx possible for PT: 1,680,238,080,000,000 (1.7 quatrillion)
17             # JnxPTEpoch -> `pt __nWO0000` -> Midnight Jan. 1 7039 BCE
18             # PTEpoch -> `pt _nWO` -> Midnight Jan. 1 1361 CE
19             # Frame members:
20             # new inits either with pt-param, expanded, or empty
21             #
22             # settle fields (like return new Frame object with only total secs of old)
23             # re-def frame as other than 60th-of-a-second
24             # re-def jink as other than 60th-of-a-frame
25             # eg. def f && j limits as 31.6227766016838 (sqrt(1000)) for ms jinx
26             # or just def f as 1000 for exactly ms frames
27             # allow month/year modes to be set to avg or relative
28             #
29             # My Base64 encoding uses characters: 0-9 A-Z a-z . _ since I don't like
30             # having spaces or plusses in my time strings. I need times to be easy to
31             # append to filenames for very precise, consice, time-stamp versioning.
32             # Each encoded character represents (normally) just a single date or time
33             # field. All fields are 0-based except Month && Day. The fields are:
34             # Year-2000, Month, Day, Hour, Minute, Second, Frame (60th-of-a-second)
35             # There are three (3) exceptions to the rule that each character only
36             # represents one date or time field. The bits are there so... why not? =)
37             # 0) Each 12 added to the Month adds 64 to the Year.
38             # 1) 24 added to the Hour adds 320 to the Year.
39             # 2) 31 added to the Day makes the year negative just before adding
40             # 2000.
41              
42             =head1 NAME
43              
44             Time::Frame - objects to store a length of time
45              
46             =head1 VERSION
47              
48             This documentation refers to version 1.2.565EHOV of
49             Time::Frame, which was released on Sun Jun 5 14:17:24:31 2005.
50              
51             =head1 SYNOPSIS
52              
53             use Time::Frame;
54            
55             my $f = Time::Frame->new('verbose' => '2 weeks');
56             print 'Number of days is ', $f->day(), "\n";
57              
58             =head1 DESCRIPTION
59              
60             This module has been adapted from the Time::Seconds module
61             written by Matt Sergeant && Jarkko
62             Hietaniemi . Time::Frame inherits base
63             data structure && object methods from Time::Fields.
64             Frame was written to simplify storage && calculation
65             of encoded, yet distinct && human-readable, time data
66             objects.
67              
68             The title of this Perl module has dual meaning. Frame
69             means both the span of time the whole object represents
70             as well as the (default) smallest unit of measurement.
71              
72             =head1 2DO
73              
74             =over 2
75              
76             =item - copy total_frames into AUTOLOAD for (in|as|total)_(CYMDhmsfj)
77             functions which convert to any field
78              
79             =item - better ways to specify common verbose sizes
80              
81             =item - What else does Frame need?
82              
83             =back
84              
85             =head1 WHY?
86              
87             The reason I created Frame was that I have grown so enamored with
88             Base64 representations of everything around me that I was
89             compelled to write a simple clock utility ( `pt` ) using Base64.
90             This demonstrated the benefit to be gained from time objects with
91             distinct fields && configurable precision. Thus, L
92             was written to be the abstract base class for:
93              
94             Time::Frame ( creates objects which represent spans of time )
95             &&
96             Time::PT ( creates objects which represent instants in time )
97              
98             =head1 USAGE
99              
100             Many of Time::Frame's methods have been patterned after the excellent
101             L module written by Matt Sergeant
102             && Jarkko Hietaniemi .
103              
104             =head2 new(, )
105              
106             Time::Frame's constructor can be called as a class method to create a
107             brand new object or as an object method to copy an existing object.
108             Beyond that, new() can initialize Frame objects in the following ways:
109              
110             *
111             eg. Time::Frame->new('0123456789');
112             * 'str' =>
113             eg. Time::Frame->new('str' => '0A1B2C3D4E');
114             * 'list' =>
115             eg. Time::Frame->new('list' => [0, 1, 2..9]);
116             * 'hash' =>
117             eg. Time::Frame->new('hash' => {'jink' => 8, 'year' => 2003})
118              
119             =head2 total_frames()
120              
121             total_frames simply returns the total number of frames a Time::Frame
122             object specifies.
123              
124             =head2 color()
125              
126             This is an object member
127             which will join Base64 representations of each field that has
128             been specified in use() && joins them with color-codes or color
129             escape sequences with formats for varied uses. Currently
130             available DestinationColorTypeFormats are:
131              
132             'ANSI' # eg. \e[1;32m
133             'zsh' # eg. %{\e[1;33m%}
134             'HTML' # eg.
135             'Simp' # eg. RbobYbGbCbUbPb
136              
137             The following methods allow access to individual fields of
138             Time::Frame objects:
139              
140             $t->C or $t->century
141             $t->Y or $t->year
142             $t->M or $t->month
143             $t->D or $t->day
144             $t->h or $t->hour
145             $t->m or $t->minute
146             $t->s or $t->second
147             $t->f or $t->frame
148             $t->j or $t->jink
149             $t->z or $t->zone
150              
151             Please see L for a more thorough description of field
152             accessor methods.
153              
154             =head1 NOTES
155              
156             Whenever individual Time::Frame attributes are going to be
157             printed or an entire object can be printed with multi-colors,
158             the following mapping should be employed whenever possible:
159              
160             D Century -> DarkRed
161             A Year -> Red
162             T Month -> Orange
163             E Day -> Yellow
164             hour -> Green
165             t minute -> Cyan
166             i second -> Blue
167             m frame -> Purple
168             e jink -> DarkPurple
169             zone -> Grey or White
170              
171             Please see the color() member function in the USAGE section.
172              
173             I hope you find Time::Frame useful. Please feel free to e-mail
174             me any suggestions || coding tips || notes of appreciation
175             ("app-ree-see-ay-shun"). Thank you. TTFN.
176              
177             =head1 CHANGES
178              
179             Revision history for Perl extension Time::Frame:
180              
181             =over 4
182              
183             =item - 1.2.565EHOV Sun Jun 5 14:17:24:31 2005
184              
185             * combined Fields, Frame, && PT into one pkg (so see PT CHANGES section
186             for updates to Fields or Frame)
187              
188             =item - 1.0.3CCA3bG Fri Dec 12 10:03:37:16 2003
189              
190             * removed indenting from POD NAME field
191              
192             =item - 1.0.3CB7RLu Thu Dec 11 07:27:21:56 2003
193              
194             * added HTML color option && prepared for release
195              
196             =item - 1.0.3CA8thM Wed Dec 10 08:55:43:22 2003
197              
198             * built class to inherit from Time::Fields
199              
200             =item - 1.0.37VG26k Thu Jul 31 16:02:06:46 2003
201              
202             * original version
203              
204             =back
205              
206             =head1 INSTALL
207              
208             Please run:
209              
210             `perl -MCPAN -e "install Time::PT"`
211              
212             or uncompress the package && run the standard:
213              
214             `perl Makefile.PL; make; make test; make install`
215              
216             =head1 FILES
217              
218             Time::Frame requires:
219              
220             L to allow errors to croak() from calling sub
221              
222             L to handle number-base conversion
223              
224             L to provide underlying object structure
225              
226             =head1 SEE ALSO
227              
228             L
229              
230             =head1 LICENSE
231              
232             Most source code should be Free!
233             Code I have lawful authority over is && shall be!
234             Copyright: (c) 2003-2004, Pip Stuart.
235             Copyleft : This software is licensed under the GNU General Public
236             License (version 2), && as such comes with NO WARRANTY. Please
237             consult the Free Software Foundation (http://FSF.Org) for
238             important information about your freedom.
239              
240             =head1 AUTHOR
241              
242             Pip Stuart
243              
244             =cut
245              
246             package Time::Frame;
247 1     1   4 use strict;
  1         1  
  1         41  
248             require Time::Fields;
249 1     1   6 use base qw( Time::Fields );
  1         2  
  1         100  
250 1     1   5 use vars qw( $AUTOLOAD );
  1         1  
  1         32  
251 1     1   4 use Carp;
  1         2  
  1         51  
252 1     1   6 use Math::BaseCnv qw( :all );
  1         1  
  1         229  
253             our $VERSION = '1.2.565EHOV'; # major . minor . PipTimeStamp
254             our $PTVR = $VERSION; $PTVR =~ s/^\d+\.\d+\.//; # strip major && minor
255             # Please see `perldoc Time::PT` for an explanation of $PTVR.
256 1     1   6 use constant ONE_MINUTE => '1 min'; # 60;
  1         1  
  1         66  
257 1     1   5 use constant ONE_HOUR => '1 hour'; # 3_600;
  1         1  
  1         41  
258 1     1   4 use constant ONE_DAY => '1 day'; # 86_400;
  1         2  
  1         44  
259 1     1   4 use constant ONE_WEEK => '1 week'; # 604_800;
  1         1  
  1         34  
260 1     1   4 use constant ONE_REAL_MONTH => '1 month'; # '1M';
  1         6  
  1         32  
261 1     1   4 use constant ONE_REAL_YEAR => '1 year'; # '1Y';
  1         2  
  1         35  
262 1     1   5 use constant ONE_MONTH => '1 average month'; # 2_629_744;
  1         1  
  1         31  
263             # ONE_YEAR / 12
264 1     1   5 use constant ONE_FINANCIAL_MONTH => '1 financial month'; # 2_592_000;
  1         2  
  1         59  
265             # 30 days
266 1     1   4 use constant ONE_YEAR => '1 average year'; # 31_556_930;
  1         2  
  1         34  
267             # 365.24225 days
268 1     1   5 use constant LEAP_YEAR => '1 leap year'; # 31_622_400;
  1         7  
  1         35  
269             # 366 * ONE_DAY
270 1     1   4 use constant NON_LEAP_YEAR => '1 nonleap year'; # 31_536_000;
  1         12  
  1         108  
271             # 365 * ONE_DAY
272              
273             use overload
274 1         13 q("") => \&_stringify,
275             q(<=>) => \&_cmp_num,
276             q(cmp) => \&_cmp_str,
277             q(+) => \&_add,
278 1     1   7 q(-) => \&_sub;
  1         2  
279              
280             sub _stringify { # cat non-zero b64 fields down to frame or should just be used fields
281 0     0     my @fdat = $_[0]->CYMDhmsfjz();
282 0           my @attz = $_[0]->_attribute_names();
283 0           my $tstr = ''; my $toob = 0; # flag designating field too big
  0            
284 0           foreach(@fdat) {
285 0 0         $toob = 1 if($_ > 63);
286             }
287 0 0         if($toob) {
288 0           for(my $i=0; $i<@fdat; $i++) {
289 0           $attz[$i] =~ s/^_(.).*/$1/;
290 0 0 0       $attz[$i] = uc($attz[$i]) if($i < 4 || $i == $#fdat);
291 0           $tstr .= $attz[$i] . ':' . $fdat[$i];
292 0 0         $tstr .= ', ' if($i < $#fdat);
293             }
294             } else {
295 0           for(my $i=0; $i<@fdat; $i++) {
296 0 0         if($fdat[$i]) {
297 0           $tstr .= b64($fdat[$i]);
298 0           while($i < 7) { $tstr .= b64($fdat[++$i]); }
  0            
299             }
300             }
301             }
302 0           return($tstr);
303             }
304              
305             sub _cmp_num {
306 0     0     my ($larg, $rarg, $srvr) = @_;
307 0 0         ($larg, $rarg) = ($rarg, Time::Frame->new($larg)) if($srvr); # mk both args Frame objects
308             # maybe compare _total_jinx() or something
309 0           return(0);
310             }
311              
312             sub _cmp_str {
313 0     0     my $r = _cmp_num(@_);
314 0 0         ($r < 0) ? return('lt') : ($r) ? return('gt') : return('eq');
    0          
315             }
316              
317             # Frame + Frame = Frame
318             # Frame + PT = PT (calculation is passed off to PT.pm)
319             # Frame + 'str' = PT (passed off to PT.pm after PT->new('str') is made)
320             # Frame + anything else is not supported yet
321             sub _add {
322 0     0     my ($larg, $rarg, $srvr) = @_; my $rslt;
  0            
323 0 0         $larg = Time::PT->new($larg) if($srvr);
324 0 0 0       $rarg = Time::PT->new($rarg) unless(ref($rarg) && $rarg->isa('Time::Frame'));
325 0 0 0       if((ref($larg) && $larg->isa('Time::PT')) ||
      0        
      0        
326             (ref($rarg) && $rarg->isa('Time::PT'))) {
327 0           $rslt = $larg + $rarg; # pass off calculation to PT.pm
328             } else {
329 0           $rslt = Time::Frame->new();
330 0           $rslt->{'_zone'} = $larg->z + $rarg->z;
331 0           $rslt->{'_jink'} = $larg->j + $rarg->j;
332 0           $rslt->{'_frame'} = $larg->f + $rarg->f;
333 0           $rslt->{'_second'} = $larg->s + $rarg->s;
334 0           $rslt->{'_minute'} = $larg->i + $rarg->i;
335 0           $rslt->{'_hour'} = $larg->h + $rarg->h;
336 0           $rslt->{'_day'} = $larg->D + $rarg->D;
337 0           $rslt->{'_month'} = $larg->O + $rarg->O;
338 0           $rslt->{'_year'} = $larg->Y + $rarg->Y;
339 0           $rslt->{'_century'} = $larg->C + $rarg->C;
340             }
341 0           return($rslt);
342             }
343              
344             # Frame - Frame = Frame
345             # 'str' - Frame = PT (passed off to PT.pm after PT->new('str') is made)
346             # Frame - anything else is not supported yet
347             sub _sub {
348 0     0     my ($larg, $rarg, $srvr) = @_; my $rslt;
  0            
349 0 0         $larg = Time::PT->new($larg) if($srvr);
350 0 0 0       if(ref($larg) && $larg->isa('Time::PT')) {
351 0           $rslt = $larg - $rarg; # pass off calculation to PT.pm
352             } else {
353 0 0 0       $rarg = Time::Frame->new($rarg) unless(ref($rarg) && $rarg->isa('Time::Frame'));
354 0           $rslt = Time::Frame->new();
355 0           $rslt->{'_zone'} = $larg->z - $rarg->z;
356 0           $rslt->{'_jink'} = $larg->j - $rarg->j;
357 0           $rslt->{'_frame'} = $larg->f - $rarg->f;
358 0           $rslt->{'_second'} = $larg->s - $rarg->s;
359 0           $rslt->{'_minute'} = $larg->i - $rarg->i;
360 0           $rslt->{'_hour'} = $larg->h - $rarg->h;
361 0           $rslt->{'_day'} = $larg->D - $rarg->D;
362 0           $rslt->{'_month'} = $larg->O - $rarg->O;
363 0           $rslt->{'_year'} = $larg->Y - $rarg->Y;
364 0           $rslt->{'_century'} = $larg->C - $rarg->C;
365             }
366 0           return($rslt);
367             }
368              
369             sub _color_fields {
370 0     0     my $self = shift;
371 0 0 0       my $fstr = shift || ' ' x 10; $fstr =~ s/^0+// if(length($fstr) <= 7);
  0            
372 0   0       my $ctyp = shift || 'Simp';
373 0           my @clrz = (); my $coun = 0; my $rstr = '';
  0            
  0            
374 0 0         if ($ctyp =~ /^s/i) { # simp color codes
    0          
    0          
375 0           @clrz = @{$self->_field_colors('simp')};
  0            
376 0 0         if(length($fstr) > 7) {
377 0           while(length($fstr) > $coun) { $rstr .= $clrz[$coun++]; }
  0            
378             } else {
379 0           while(length($fstr) > $coun) { $rstr .= $clrz[(8 - length($fstr) + $coun++)]; }
  0            
380             }
381             } elsif($ctyp =~ /^h/i) { # HTML link && font color tag delimiters
382 0           @clrz = @{$self->_field_colors('html')};
  0            
383 0           $_ = '' foreach(@clrz);
384 0           $rstr = '';
385 0 0         if(length($fstr) > 7) {
386 0           while(length($fstr) > $coun) { $rstr .= $clrz[$coun] . substr($fstr, $coun++, 1) . ''; }
  0            
387             } else {
388 0           while(length($fstr) > $coun) { $rstr .= $clrz[(8 - length($fstr) + $coun)] . substr($fstr, $coun++, 1) . ''; }
  0            
389             }
390 0           $rstr .= '';
391             } elsif($ctyp =~ /^4/i) { # 4nt prompt needs verbose color codes
392 0           @clrz = @{$self->_field_colors('4nt')};
  0            
393 0           for(my $i=0; $i<@clrz; $i++) {
394 0           $clrz[$i] = ' & color ' . $clrz[$i] . ' & echos ';
395             }
396 0 0         if(length($fstr) > 7) {
397 0           while(length($fstr) > $coun) { $rstr .= $clrz[$coun] . substr($fstr, $coun++, 1); }
  0            
398             } else {
399 0           while(length($fstr) > $coun) { $rstr .= $clrz[(1 + $coun)] . substr($fstr, $coun++, 1); }
  0            
400             }
401             } else { # ANSI escapes
402 0           @clrz = @{$self->_field_colors('ansi')};
  0            
403 0 0         if($ctyp =~ /^z/i) { # zsh prompt needs delimited %{ ANSI %}
404 0           for(my $i=0; $i<@clrz; $i++) { $clrz[$i] = '%{' . $clrz[$i] . '%}'; }
  0            
405             }
406 0 0         if(length($fstr) > 7) {
407 0           while(length($fstr) > $coun) { $rstr .= $clrz[$coun] . substr($fstr, $coun++, 1); }
  0            
408             } else {
409 0           while(length($fstr) > $coun) { $rstr .= $clrz[(8 - length($fstr) + $coun)] . substr($fstr, $coun++, 1); }
  0            
410             }
411             }
412 0           return($rstr);
413             }
414              
415             # Time::Frame object constructor as class method or copy as object method.
416             # First param can be ref to copy. Not including optional ref from
417             # copy, default is no params to create a new empty Frame object.
418             # If params are supplied, they must be a single key && a single value.
419             # The key must be one of the following 3 types of constructor
420             # initialization mechanisms:
421             # -1) (eg. '0A1B2C3D4E')
422             # 0) 'str' => (eg. 'str' => '0A1B2C3D4E')
423             # 1) 'list' => (eg. 'list' => [0, 1, 2..9])
424             # 2) 'hash' => (eg. 'hash' => {'jink' => 8})
425             sub new {
426 0     0 1   my ($nvkr, $ityp, $idat) = @_;
427 0           my $nobj = ref($nvkr);
428 0           my $clas = $ityp;
429 0 0 0       $clas = $nobj || $nvkr if(!defined($ityp) || $ityp !~ /::/);
      0        
430 0           my $self = Time::Fields->new($clas);
431 0           my @attz = $self->_attribute_names();
432 0           foreach my $attr ( @attz ) { #$self->_attribute_names() ) {
433             # $self->{$attr} = $self->_default_value($attr); # init defaults
434 0 0         $self->{$attr} = $nvkr->{$attr} if($nobj); # && copy if supposed to
435             }
436 0 0 0       if(defined($ityp) && $ityp !~ /::/) { # there were initialization params
437 0 0         ($ityp, $idat) = ('str', $ityp) unless(defined($idat));
438 0 0 0       if($ityp =~ /^verbose$/i) { # handle 'verbose' differently
    0          
439             # verbose string param has decimal numbers followed by full field names
440 0           while($idat =~ s/(\d+)\s*(\w+)//) {
441 0           my($fval, $fnam) = ($1, lc($2));
442 0           $fnam =~ s/s$//; # strip ending 's'
443             # should do some testing of fnam to turn into closest _attribute_name if ! one
444 0 0         if($fnam =~ /^w/) { $self->{'_day'} += (7 * $fval); }
  0            
445 0           else { $self->{('_' . $fnam)} += $fval; }
446             }
447             } elsif($ityp =~ /^s/i && length($idat) < 9) { # handle small 'str' differently
448             # small str param grows left from frame field if shorter than 9 chars
449 0           my $ilen = length($idat);
450 0           for(my $i = (8-$ilen); $i < 8; $i++) {
451 0 0         if($idat =~ s/^(.)//) {
452 0           $self->{$attz[$i]} = b10($1); # break down str
453             }
454             }
455             } else {
456 0           foreach my $attr ( @attz ) {
457 0 0         if ($ityp =~ /^s/i) { # 'str'
    0          
    0          
458 0 0         $self->{$attr} = b10($1) if($idat =~ s/^(.)//); # break down string
459             } elsif($ityp =~ /^[la]/i) { # 'list' or 'array'
460 0 0         $self->{$attr} = shift( @{$idat} ) if(@{$idat}); # shift list vals
  0            
  0            
461             } elsif($ityp =~ /^h/i) { # 'hash'
462             # do some searching to find hash key that matches
463 0           foreach(keys(%{$idat})) {
  0            
464 0 0         if($attr =~ /$_/) {
465 0           $self->{$attr} = $idat->{$_};
466 0           delete($idat->{$_});
467             }
468             }
469             } else { # undetected init type
470 0           croak "!*EROR*! Time::Frame::new initialization type: $ityp did not match 'str', 'list', or 'hash'!\n";
471             }
472             }
473             }
474             }
475 0           return($self);
476             }
477              
478             sub total_frames { # return the integer number of frames in a Time::Frame obj
479 0     0 1   my $self = shift; my $totl = 0;
  0            
480 0           $totl += ($self->j() * (1.0 / 60.0));
481 0           $totl += $self->f();
482 0           $totl += ($self->s() * 60);
483 0           $totl += ($self->m() * 60 * 60);
484 0           $totl += ($self->h() * 60 * 60 * 60);
485 0           $totl += ($self->D() * 60 * 60 * 60 * 24);
486 0           $totl += ($self->M() * 60 * 60 * 60 * 24 * 30.4368537808642);
487 0           $totl += ($self->Y() * 60 * 60 * 60 * 24 * 365.24225);
488 0           $totl += ($self->C() * 60 * 60 * 60 * 24 * 365.24225 * 100);
489 0           return($totl);
490             }
491              
492             #sub AUTOLOAD { # methods (created as necessary)
493             # no strict 'refs';
494             # my ($self, $nwvl) = @_;
495             #
496             # # normal set_/get_ methods
497             #
498             # if ($AUTOLOAD =~ /.*::[sg]et(_\w+)/i) {
499             # my $atnm = lc($1);
500             # *{$AUTOLOAD} = sub { $_[0]->{$atnm} = $_[1] if(@_ > 1); return($_[0]->{$atnm}); };
501             # $self->{$atnm} = $nwvl if(@_ > 1);
502             # return($self->{$atnm});
503             # # use_??? to set/get field filters
504             # } elsif($AUTOLOAD =~ /.*::(use_\w+)/i) {
505             # my $atnm = '__' . lc($1);
506             # *{$AUTOLOAD} = sub { $_[0]->{$atnm} = $_[1] if(@_ > 1); return($_[0]->{$atnm}); };
507             # $self->{$atnm} = $nwvl if(@_ > 1);
508             # return($self->{$atnm});
509             # # Alias methods which must be detected before sweeps
510             # } elsif($AUTOLOAD =~ /.*::time$/i) {
511             # *{$AUTOLOAD} = sub { return($self->hms()); };
512             # return($self->hms());
513             # } elsif($AUTOLOAD =~ /.*::dt$/i) {
514             # *{$AUTOLOAD} = sub { return($self->CYMDhmsfjz()); };
515             # return($self->CYMDhmsfjz());
516             # } elsif($AUTOLOAD =~ /.*::mday$/i) { my $atnm = '_day';
517             # *{$AUTOLOAD} = sub { $_[0]->{$atnm} = $_[1] if(@_ > 1); return($_[0]->{$atnm}); };
518             # $self->{$atnm} = $nwvl if(@_ > 1); return($self->{$atnm});
519             # # all joint field methods (eg. YMD(), hms(), foo(), etc.
520             # } elsif($AUTOLOAD =~ /.*::([CYMODhmisfjz][CYMODhmisfjz]+)$/i) {
521             # my @fldl = split(//, $1);
522             # my ($self, @nval) = @_; my @rval = (); my $atnm = ''; my $rgex;
523             # # handle Month / minute exceptions
524             # for(my $i=0; $i<$#fldl; $i++) {
525             # $fldl[$i + 1] = 'O' if($fldl[$i] =~ /[yd]/i && $fldl[$i + 1] eq 'm');
526             # $fldl[$i ] = 'O' if($fldl[$i] eq 'm' && $fldl[$i + 1] =~ /[yd]/i);$ $fldl[$i ] = 'O' if($fldl[$i] eq 'M');
527             # $fldl[$i ] = 'i' if($fldl[$i] eq 'm');
528             # }
529             # *{$AUTOLOAD} = sub {
530             # my ($self, @nval) = @_; my @rval = ();
531             # for(my $i=0; $i<@fldl; $i++) {
532             # foreach my $attr ($self->_attribute_names()){
533             # my $mtch = $self->_attribute_match($attr);
534             # if(defined($mtch) && $fldl[$i] =~ /^$mtch/i) {
535             # $self->{$attr} = $nval[$i] if($i < @nval);
536             # push(@rval, $self->{$attr});
537             # }
538             # }
539             # }
540             # return(@rval);
541             # };
542             # for(my $i=0; $i<@fldl; $i++) {
543             # foreach my $attr ($self->_attribute_names()){
544             # my $mtch = $self->_attribute_match($attr);
545             # if(defined($mtch) && $fldl[$i] =~ /$mtch/i) {
546             # $self->{$attr} = $nval[$i] if($i < @nval);
547             # push(@rval, $self->{$attr});
548             # }
549             # }
550             # }
551             # return(@rval);
552             # # sweeping matches to handle partial keys
553             # } elsif($AUTOLOAD =~ /.*::[-_]?([CYMODhmisfjz])(.)?/i) {
554             # my ($atl1, $atl2) = ($1, $2); my $atnm;
555             # $atl1 = 'O' if($atl1 eq 'm' && defined($atl2) && lc($atl2) eq 'o');
556             # $atl1 = 'i' if($atl1 eq 'M' && defined($atl2) && lc($atl2) eq 'i');
557             # $atl1 = 'O' if($atl1 eq 'M');
558             # $atl1 = 'i' if($atl1 eq 'm');
559             # foreach my $attr ($self->_attribute_names()) {
560             # my $mtch = $self->_attribute_match($attr);
561             # $atnm = $attr if(defined($mtch) && $atl1 =~ /$mtch/i);
562             # }
563             # *{$AUTOLOAD} = sub { $_[0]->{$atnm} = $_[1] if(@_ > 1); return($_[0]->{$atnm}); };
564             # $self->{$atnm} = $nwvl if(@_ > 1);
565             # return($self->{$atnm});
566             # } else {
567             # croak "No such method: $AUTOLOAD\n";
568             # }
569             #}
570              
571 0     0     sub DESTROY { } # do nothing but define in case && to calm warning in test.pl
572              
573             127;