File Coverage

lib/Date/Manip/Obj.pm
Criterion Covered Total %
statement 154 167 93.4
branch 64 68 95.5
condition 15 18 83.3
subroutine 22 23 95.6
pod 14 14 100.0
total 269 290 93.7


line stmt bran cond sub pod time code
1             package Date::Manip::Obj;
2             # Copyright (c) 2008-2023 Sullivan Beck. All rights reserved.
3             # This program is free software; you can redistribute it and/or modify it
4             # under the same terms as Perl itself.
5              
6             ########################################################################
7             ########################################################################
8              
9             require 5.010000;
10 168     168   1116 use warnings;
  168         341  
  168         6021  
11 168     168   1026 use strict;
  168         355  
  168         5220  
12 168     168   879 use IO::File;
  168         303  
  168         24313  
13 168     168   100752 use Storable qw(dclone);
  168         529545  
  168         10333  
14 168     168   1195 use Carp;
  168         355  
  168         277336  
15              
16             our ($VERSION);
17             $VERSION='6.91';
18 168     168   0 END { undef $VERSION; }
19              
20             ########################################################################
21             # METHODS
22             ########################################################################
23              
24             my %classes = ( 'Date::Manip::Base' => 1,
25             'Date::Manip::TZ' => 1,
26             'Date::Manip::Date' => 1,
27             'Date::Manip::Delta' => 1,
28             'Date::Manip::Recur' => 1,
29             );
30              
31             sub new {
32 21227     21227 1 132348 my(@args) = @_;
33 21227         36859 my(@allargs) = @args;
34              
35             # $old is the object (if any) being used to create a new object
36             # $new is the new object
37             # $class is the class of the new object
38             # $tz is a Date::Manip::TZ object to base the new object on
39             # (only for Date, Delta, Recur objects)
40             # $base is the Date::Manip::Base object to base the new object on
41             # @opts options to pass to config method
42              
43 21227         33334 my($old,$new,$class,$tz,$base,@opts);
44              
45             # Get the class of the new object
46              
47 21227 100       46205 if (exists $classes{ $args[0] }) {
48              
49             # $obj = new CLASS
50 21214         34967 $class = shift(@args);
51              
52             } else {
53              
54             # $obj->new
55 13         27 $class = ref($args[0]);
56             }
57              
58             # Find out if there are any config options (which will be the
59             # final argument).
60              
61 21227 100 100     88684 if (@args && ref($args[$#args]) eq 'ARRAY') {
62 16         21 @opts = @{ pop(@args) };
  16         57  
63             }
64              
65             # Get an old object
66              
67 21227 100       84676 if (ref($args[0]) =~ /^Date::Manip/) {
68             # $old->new
69             # new CLASS $old
70 19777         34336 $old = shift(@args);
71             }
72              
73             # Additional arguments will be passed to parse.
74              
75             ########################
76              
77             # Get Base/TZ objects from an existing object
78              
79 21227 100       44240 if ($old) {
80 19777 100       49229 if (ref($old) eq 'Date::Manip::Base') {
    100          
81 17         28 $base = $old;
82             } elsif (ref($old) eq 'Date::Manip::TZ') {
83 3         11 $tz = $old;
84 3         10 $base = $$tz{'base'};
85              
86             # *** I think this is useless code, deprecate
87             # } elsif (ref($old) eq 'ARRAY') {
88             # my %old = @$old;
89             # $tz = $old{'tz'};
90             # $base = $$tz{'base'};
91              
92             } else {
93 19757         31831 $tz = $$old{'tz'};
94 19757         30796 $base = $$tz{'base'};
95             }
96             }
97              
98             # Create a new empty object.
99              
100             $new = {
101 21227         62142 'data' => {},
102             'err' => '',
103             };
104              
105             # Create Base/TZ objects if necessary
106              
107 21227 100 100     75237 if ($base && @opts) {
108 13         27 $base = _clone($base);
109 13 100       66 $tz = new Date::Manip::TZ $base if ($tz);
110             }
111              
112 21227         31802 my $init = 1;
113 21227 100       48924 if ($class eq 'Date::Manip::Base') {
    100          
114 503 100       1603 if ($base) {
115             # new Date::Manip::Base $base
116             #
117             # We have to clone it (which we already did if @opts was given)
118             #
119 4 100       20 if (@opts) {
120 2         5 $new = $base;
121             } else {
122 2         10 $new = _clone($base);
123             }
124 4         9 $init = 0;
125             }
126              
127             } elsif ($class eq 'Date::Manip::TZ') {
128 512 100       2319 if ($tz) {
    100          
129             # new Date::Manip::TZ $tz
130 3 100       11 if (@opts) {
131 2         6 $new = $tz;
132             } else {
133 1         3 $new = _clone($tz);
134             }
135 3         6 $init = 0;
136             } elsif (! $base) {
137 496         3436 $base = new Date::Manip::Base;
138             }
139 512         2277 $$new{'base'} = $base;
140              
141             } else {
142 20212 100       38731 if (! $tz) {
143 456 100       1209 if ($base) {
144 1         4 $tz = new Date::Manip::TZ $base;
145             } else {
146 455         3057 $tz = new Date::Manip::TZ;
147             }
148             }
149 20212         36687 $$new{'tz'} = $tz;
150             }
151              
152 21227         42023 $$new{'args'} = [ @args ];
153 21227         38684 bless $new,$class;
154              
155 21227 100       82609 $new->_init() if ($init);
156 21227 100       48882 $new->config(@opts) if (@opts);
157 21227 100       40854 $new->_init_args() if (@args);
158 21227         61140 $new->_init_final();
159 21227         61309 return $new;
160             }
161              
162             # This clones an object. Currently, it only clones a Base or TZ
163             # object, but dclone can't handle stored regexps so we have to copy
164             # them manually.
165             #
166             sub _clone {
167 16     16   32 my($obj) = @_;
168              
169 16 100       38 if (ref($obj) eq 'Date::Manip::Base') {
170              
171 15         29 my $tmp = $$obj{'data'}{'rx'};
172 15         31 delete $$obj{'data'}{'rx'};
173 15         9394 my $new = dclone($obj);
174 15         64 $$obj{'data'}{'rx'} = $tmp;
175 15         28 $$new{'data'}{'rx'} = $tmp;
176 15         48 return $new;
177              
178             } else {
179              
180 1         3 my $base = $$obj{'base'};
181 1         2 delete $$obj{'base'};
182              
183 1         5 my @rx = qw(namerx zonerx abbrx offrx zrx offabbrx orrparrx);
184 1         2 my @tmp;
185 1         4 foreach my $rx (@rx) {
186 7         15 push(@tmp,$$obj{'data'}{$rx});
187 7         9 delete $$obj{'data'}{$rx};
188             }
189              
190 1         2572 my $new = dclone($obj);
191              
192 1         7 foreach my $rx (@rx) {
193 7         9 my $r = shift(@tmp);
194 7         14 $$obj{'data'}{$rx} = $r;
195 7         14 $$new{'data'}{$rx} = $r;
196             }
197              
198 1         3 $$obj{'base'} = $base;
199 1         2 $$new{'base'} = $base;
200 1         5 return $new;
201             }
202             }
203              
204             # Only called if extra @args exist
205             sub _init_args {
206 0     0   0 my($self) = @_;
207              
208 0         0 my @args = @{ $$self{'args'} };
  0         0  
209 0         0 carp "WARNING: [new] invalid arguments: @args";
210              
211 0         0 return;
212             }
213              
214             sub _init_final {
215 20715     20715   34814 my($self) = @_;
216 20715         30506 return;
217             }
218              
219             sub new_config {
220 8     8 1 1429 my(@args) = @_;
221              
222             # Make sure that @opts is passed in as the final argument.
223              
224 8 100 66     46 if (! @args ||
225             ! (ref($args[$#args]) eq 'ARRAY')) {
226 6         15 push(@args,['ignore','ignore']);
227             }
228              
229 8         21 return new(@args);
230             }
231              
232             sub new_date {
233 13957     13957 1 26777 my(@args) = @_;
234 13957         74006 require Date::Manip::Date;
235 13957         39467 return new Date::Manip::Date @args;
236             }
237             sub new_delta {
238 5508     5508 1 287002 my(@args) = @_;
239 5508         121656 require Date::Manip::Delta;
240 5508         17559 return new Date::Manip::Delta @args;
241             }
242             sub new_recur {
243 277     277 1 934 my(@args) = @_;
244 277         118452 require Date::Manip::Recur;
245 277         2569 return new Date::Manip::Recur @args;
246             }
247              
248             sub base {
249 19597     19597 1 32477 my($self) = @_;
250 19597         31351 my $t = ref($self);
251 19597 100       44655 if ($t eq 'Date::Manip::Base') {
    100          
252 1         4 return undef;
253             } elsif ($t eq 'Date::Manip::TZ') {
254 17885         41991 return $$self{'base'};
255             } else {
256 1711         3024 my $dmt = $$self{'tz'};
257 1711         4454 return $$dmt{'base'};
258             }
259             }
260              
261             sub tz {
262 193     193 1 1050 my($self) = @_;
263 193         475 my $t = ref($self);
264              
265 193 100 100     1489 if ($t eq 'Date::Manip::Base' ||
266             $t eq 'Date::Manip::TZ') {
267 2         5 return undef;
268             }
269              
270 191         624 return $$self{'tz'};
271             }
272              
273             sub config {
274 467     467 1 165493 my($self,@opts) = @_;
275 467         821 my $obj;
276 467 100 100     2946 if (ref($self) eq 'Date::Manip::Base' ||
277             ref($self) eq 'Date::Manip::TZ') {
278 83         209 $obj = $self;
279             } else {
280 384         1013 $obj = $$self{'tz'};
281             }
282              
283 467         1498 while (@opts) {
284 501         1177 my $var = shift(@opts);
285 501         1032 my $val = shift(@opts);
286 501         2959 $obj->_config_var($var,$val);
287             }
288              
289 467         1419 return;
290             }
291              
292             sub get_config {
293 8     8 1 1028 my($self,@args) = @_;
294              
295 8         12 my $base;
296 8         13 my $t = ref($self);
297 8 100       20 if ($t eq 'Date::Manip::Base') {
    100          
298 2         4 $base = $self;
299             } elsif ($t eq 'Date::Manip::TZ') {
300 2         4 $base = $$self{'base'};
301             } else {
302 4         13 my $dmt = $$self{'tz'};
303 4         9 $base = $$dmt{'base'};
304             }
305              
306 8 100       17 if (@args) {
307 7         11 my @ret;
308 7         12 foreach my $var (@args) {
309             # uncoverable branch false
310 8 50       32 if (exists $$base{'data'}{'sections'}{'conf'}{lc($var)}) {
311 8         24 push @ret,$$base{'data'}{'sections'}{'conf'}{lc($var)};
312             } else {
313             # uncoverable statement
314 0         0 carp "ERROR: [config] invalid config variable: $var";
315             # uncoverable statement
316 0         0 return '';
317             }
318             }
319              
320 7 100       15 if (@ret == 1) {
321 6         18 return $ret[0];
322             } else {
323 1         6 return @ret;
324             }
325             }
326              
327 1         4 my @ret = sort keys %{ $$base{'data'}{'sections'}{'conf'} };
  1         14  
328 1         9 return @ret;
329             }
330              
331             sub err {
332 11013     11013 1 46473 my($self,$arg) = @_;
333 11013 100       19333 if ($arg) {
334 1419         2456 $$self{'err'} = '';
335 1419         2813 return;
336             } else {
337 9594         27503 return $$self{'err'};
338             }
339             }
340              
341             sub is_date {
342 2     2 1 3588 return 0;
343             }
344             sub is_delta {
345 2     2 1 343 return 0;
346             }
347             sub is_recur {
348 2     2 1 220 return 0;
349             }
350              
351             sub version {
352 168     168 1 687 my($self,$flag) = @_;
353 168 50 33     1058 if ($flag && ref($self) ne 'Date::Manip::Base') {
354 0         0 my $dmt;
355 0 0       0 if (ref($self) eq 'Date::Manip::TZ') {
356 0         0 $dmt = $self;
357             } else {
358 0         0 $dmt = $$self{'tz'};
359             }
360 0         0 my $tz = $dmt->_now('systz');
361 0         0 return "$VERSION [$tz]";
362             } else {
363 168         1244 return $VERSION;
364             }
365             }
366              
367             1;
368             # Local Variables:
369             # mode: cperl
370             # indent-tabs-mode: nil
371             # cperl-indent-level: 3
372             # cperl-continued-statement-offset: 2
373             # cperl-continued-brace-offset: 0
374             # cperl-brace-offset: 0
375             # cperl-brace-imaginary-offset: 0
376             # cperl-label-offset: 0
377             # End: