File Coverage

lib/LEOCHARRE/Class2.pm
Criterion Covered Total %
statement 258 314 82.1
branch 86 138 62.3
condition 31 58 53.4
subroutine 48 59 81.3
pod 11 15 73.3
total 434 584 74.3


line stmt bran cond sub pod time code
1             package LEOCHARRE::Class2;
2 10     10   99031 use strict;
  10         24  
  10         419  
3 10     10   55 no strict 'refs';
  10         19  
  10         297  
4 10     10   59 use vars qw($VERSION @ISA @EXPORT);
  10         22  
  10         1431  
5 10     10   55 use Exporter;
  10         16  
  10         1669  
6             @ISA = qw/Exporter/;
7             @EXPORT = qw(
8             make_constructor
9             make_constructor_init
10             make_conf
11             make_count_for
12             make_accessor_setget_aref
13             make_accessor_get
14             make_method_counter
15             make_accessor_setget
16             make_accessor_setget_pathondisk
17             make_accessor_setget_ondisk_file
18             make_accessor_setget_ondisk_dir
19             make_accessor_setget_unique_array
20             );
21             $VERSION = sprintf "%d.%02d", q$Revision: 1.19 $ =~ /(\d+)/g;
22             # use Smart::Comments '###';
23 10     10   59 use Carp;
  10         18  
  10         40075  
24              
25             sub make_constructor {
26 10     10 1 395 my $class = shift;
27             ### $class
28 10         97 *{"$class\::new"} = sub {
29 23     23   18038 my ($class,$self) = @_;
30 23   100     200 $self||={};
31              
32 23 50 33     255 (defined $self and ref $self and ref $self eq 'HASH')
      33        
33             or confess("Argument to constructor must be a hash ref");
34              
35 23         60 bless $self, $class;
36 23         72 return $self;
37 10         69 };
38             }
39              
40             sub make_constructor_init {
41 1     1 1 114 my $class = shift;
42             ### $class
43 1         11 *{"$class\::new"} = sub {
44 1     1   1621 my ($class,$self) = @_;
45 1   50     9 $self||={};
46            
47 1 50 33     21 (defined $self and ref $self and ref $self eq 'HASH')
      33        
48             or confess("Argument to constructor must be a hash ref");
49              
50              
51 1         3 bless $self, $class;
52 1 50       35 if ($class->can('init')){
53 1         6 $self->init;
54             }
55 1         18 return $self;
56 1         9 };
57             }
58              
59              
60              
61             sub make_accessor_setget {
62 5     5 1 48 my $class = shift;
63 5 50       22 defined $class or die;
64              
65 5         28 for ( ___resolve_args(@_) ){
66 12         34 _make_setget($class,@$_);
67             }
68             }
69              
70             sub make_accessor_get {
71 1     1 1 9 my $class = shift;
72 1 50       4 defined $class or die;
73              
74 1         3 for ( ___resolve_args(@_) ){
75 1         4 _make_get($class,@$_);
76             }
77             }
78              
79              
80             sub make_accessor_setget_ondisk_file {
81 1     1 1 7 my $class = shift;
82 1 50       5 defined $class or die;
83              
84 1         6 for ( ___resolve_args(@_) ){
85 1         776 _make_setget_ondisk_file($class,@$_);
86             }
87             }
88              
89             sub make_accessor_setget_ondisk_dir {
90 1     1 1 10 my $class = shift;
91 1 50       4 defined $class or die;
92              
93 1         3 for ( ___resolve_args(@_) ){
94 2         6 _make_setget_ondisk_dir($class,@$_);
95             }
96             }
97              
98             sub make_accessor_setget_aref {
99 4     4 1 31 my $class = shift;
100 4 50       12 defined $class or die;
101 4         15 for ( ___resolve_args(@_) ){
102 6         622 _make_setget_aref($class,@$_);
103             }
104             }
105              
106             sub make_accessor_setget_unique_array {
107 3     3 1 25 my $class = shift;
108 3 50       15 defined $class or die;
109 3         19 for ( ___resolve_args(@_) ){
110 3         18 _make_setget_unique_array($class,@$_);
111             }
112             }
113              
114              
115              
116             sub make_method_counter {
117 1     1 1 9 my $class = shift;
118 1 50       4 defined $class or die;
119 1         2 for( ___resolve_args(@_) ){
120 1         4 _make_method_counter($class,@$_);
121             }
122             }
123             sub make_count_for {
124 1     1 1 6 my $class = shift;
125 1 50       4 defined $class or die;
126 1         3 for( ___resolve_args(@_) ){
127 2         5 _make_count_for($class,@$_);
128             }
129             }
130              
131              
132             # THE REST ARE PRIVATE METHODS
133              
134             sub ___resolve_args {
135              
136 17     17   27 my @resolved_args;
137            
138             # each one is
139             # accessor_name, accessor_default_value (can be undef)
140              
141 17         78 METHOD : while (scalar @_){
142 22         42 my $arg = shift;
143 22 50       74 defined $arg
144             or die('1.arguments must be scalars, array refs, or hash refs, not undef or false');
145             ### ARG START -----------------------------------------------
146             ### $arg
147 22 100       684 if ( my $ref = ref $arg ){ # make_accessor__ ( {} [])
148            
149 11 100       58 if ( $ref eq 'ARRAY' ){
    50          
150             ### arg is aref
151 3         6 push @resolved_args, $arg; # keep as is..
152 3         12 next METHOD;
153             }
154            
155             elsif ( $ref eq 'HASH' ){
156             ### arg is hashref
157 8         50 while( my ($name, $default_value) = each %$arg ){
158 14         2016 push @resolved_args, [ $name, $default_value];
159             }
160 8         45 next METHOD;
161             }
162            
163 0         0 die("2.arguments must be scalars, array refs, or hash refs, "
164             ."not undef or false or '$ref'");
165             }
166              
167             ### arg is not ref
168            
169 11         56 push @resolved_args, [$arg, undef];
170             }
171              
172 17         60 return @resolved_args;
173             }
174              
175              
176              
177             # DEFAULT SETGET ACCESSOR
178             sub _make_setget {
179 14     14   28 my($_class,$_name,$_default_value) = @_;
180 14         31 my $namespace = "$_class\::$_name";
181              
182 14         88 *{$namespace} = sub {
183 95     95   30086 my $self = shift;
184 95         120 my ($val) = @_;
185            
186 95 100       226 if( defined $val ){ # store it in object instance only
187 17         41 $self->{$_name} = $val;
188             }
189              
190             # if the key does not exist and we DO have a default in the class...
191 95 100 100     334 if( !exists $self->{$_name} and defined $_default_value ){
192              
193             # BUT, if it is a ref, COPY it
194             # IS A REF:
195 13 100       39 if ( my $ref = ref $_default_value ){
196 7 50       21 if ($ref eq 'ARRAY'){
    0          
    0          
197 7         24 $self->{$_name} = [ @$_default_value ];
198             }
199             elsif( $ref eq 'HASH' ){
200 0         0 $self->{$_name} = { %$_default_value };
201             }
202             elsif ( $ref eq 'SCALAR' ){
203 0         0 $self->{$_name} = $$_default_value;
204             }
205             else {
206 0         0 die("dont know how to use '$ref' ref as a default");
207             }
208             }
209              
210              
211             # IS NOT A REF:
212             else {
213 6         19 $self->{$_name} = $_default_value;
214             }
215            
216            
217             }
218 95         330 return $self->{$_name}; # may still be undef, that's ok
219 14         68 };
220             }
221              
222             # GET ACCESSOR
223              
224             sub _make_get {
225 1     1   3 my($_class,$_name,$_default_value) = @_;
226 1         3 my $namespace = "$_class\::$_name";
227              
228 1         6 *{$namespace} = sub {
229 5     5   618 my $self = shift;
230            
231 5 50 100     218 Carp::croak("This method does not take arguments.") if @_ and scalar @_;
232              
233             # if the key does not exist and we DO have a default in the class...
234 4 100 66     18 if( !exists $self->{$_name} and defined $_default_value ){
235              
236             # BUT, if it is a ref, COPY it
237             # IS A REF:
238 1 50       5 if ( my $ref = ref $_default_value ){
239 0 0       0 if ($ref eq 'ARRAY'){
    0          
    0          
240 0         0 $self->{$_name} = [ @$_default_value ];
241             }
242             elsif( $ref eq 'HASH' ){
243 0         0 $self->{$_name} = { %$_default_value };
244             }
245             elsif ( $ref eq 'SCALAR' ){
246 0         0 $self->{$_name} = $$_default_value;
247             }
248             else {
249 0         0 die("dont know how to use '$ref' ref as a default");
250             }
251             }
252              
253              
254             # IS NOT A REF:
255             else {
256 1         14 $self->{$_name} = $_default_value;
257             }
258            
259            
260             }
261 4         19 return $self->{$_name}; # may still be undef, that's ok
262 1         6 };
263              
264             }
265              
266              
267              
268             # counter
269             sub _make_method_counter {
270 1     1   2 my ($class,$name) = @_;
271 1         4 my $namespace = "$class\::$name";
272 1         16 my $datspace = "__$name\_counter__";
273              
274 1         7 *{$namespace} = sub {
275 5     5   13843 my($self,$val)=@_;
276            
277 5   100     60 $self->{$datspace} ||=0;
278            
279 5 100       24 if(defined $val){
280 3 50       21 $val=~/^\d+$/ or die("value to $namespace() must be digits");
281 3 100       14 if ($val) { #positive value
282 2         5 $self->{$datspace} = ($self->{$datspace} + $val);
283             }
284             else { # arg is 0, reset
285 1         3 $self->{$datspace} = 0;
286             }
287             }
288 5         46 return $self->{$datspace};
289 1         6 };
290             }
291              
292              
293             sub _make_setget_ondisk_file {
294 1     1   4 my($_class,$_name,$_default_value) = @_;
295 1         4 my $namespace = "$_class\::$_name";
296              
297            
298 1         11 *{$namespace} = sub {
299 4     4   26961 my $self = shift;
300 4         15 my ($val) = @_;
301            
302 4 100       59 if( defined $val ){ # store it in object instance only
303 2 100       16 my $abs = __resolve_f($val) or return;
304 1         11 $self->{$_name} = $abs;
305             }
306              
307             # if the key does not exist and we DO have a default in the class...
308 3 50 66     35 if( !exists $self->{$_name} and defined $_default_value ){
309 0 0       0 $self->{$_name} = __resolve_f($_default_value) or die;
310             }
311 3         22 return $self->{$_name}; # may still be undef, that's ok
312 1         9 };
313              
314             sub __resolve_f {
315 2     2   10 my $val = shift;
316 2         24 require Cwd;
317 2 50 0     126 my $a = Cwd::abs_path($val)
318             or warn("cant resolve $val")
319             and return;
320 2 100 50     130 -f $a or warn("not file on disk '$a'")
321             and return;
322 1         5 return $a;
323             }
324              
325             }
326              
327             sub _make_setget_ondisk_dir {
328 2     2   5 my($_class,$_name,$_default_value) = @_;
329 2         6 my $namespace = "$_class\::$_name";
330            
331              
332 2         11 *{$namespace} = sub {
333 5     5   2137 my $self = shift;
334 5         9 my ($val) = @_;
335            
336 5 100       91 if( defined $val ){ # store it in object instance only
337 2 100       8 my $abs = __resolve_d($val) or return;
338 1         4 $self->{$_name} = $abs;
339             }
340              
341             # if the key does not exist and we DO have a default in the class...
342 4 100 100     22 if( !exists $self->{$_name} and defined $_default_value ){
343 1 50       5 $self->{$_name} = __resolve_d($_default_value) or die;
344             }
345 3         13 return $self->{$_name}; # may still be undef, that's ok
346 2         11 };
347              
348             sub __resolve_d {
349 3     3   7 my $val = shift;
350 3         26 require Cwd;
351 3 50 0     213 my $abs = Cwd::abs_path($val)
352             or warn("cannot revolve '$val' with Cwd::abs_path()")
353             and return;
354 3 100 50     263 -d $abs
355             or warn("'$abs' is not a directory")
356             and return;
357 1         7 return $abs;
358             }
359             }
360              
361              
362              
363              
364             #sub make_accessor_errstr {
365             # my $class = shift;
366             # my $namespace = "$class\::errstr";
367             #}
368              
369              
370             # validate ondisk file or dir
371              
372             sub _make_method_validate_ondisk_dir {
373 0     0   0 my ($class,$name)= @_;
374              
375 0         0 my $namespace = "$class\::$name";
376 0         0 *{$namespace} = sub {
377 0     0   0 my ($self,$val) = @_;
378 0 0       0 $val or return; # croak, die, warn ??
379              
380 0         0 require Cwd;
381 0 0       0 my $abs = Cwd::abs_path($val) or return;
382 0 0       0 -d $abs and return $abs;
383 0         0 return 0;
384             }
385 0         0 }
386             sub _make_method_validate_ondisk_file {
387 0     0   0 my ($class,$name)= @_;
388              
389 0         0 my $namespace = "$class\::$name";
390 0         0 *{$namespace} = sub {
391 0     0   0 my ($self,$val) = @_;
392 0 0       0 $val or return; # croak, die, warn ??
393              
394 0         0 require Cwd;
395 0 0       0 my $abs = Cwd::abs_path($val) or return;
396 0 0       0 -f $abs and return $abs;
397 0         0 return 0;
398             }
399 0         0 }
400              
401              
402              
403              
404              
405              
406              
407             # clear methods
408             sub _make_method_clear {
409 0     0   0 my ($class,$name)= @_;
410              
411 0         0 my $namespace = "$class\::$name";
412 0         0 *{$namespace} = sub {
413 0     0   0 my $self = shift;
414 0         0 $self->{$namespace} = undef;
415 0         0 return 1;
416             }
417 0         0 }
418             sub _make_method_clear_hashref {
419 0     0   0 my ($class,$name)= @_;
420              
421 0         0 my $namespace = "$class\::$name";
422 0         0 *{$namespace} = sub {
423 0     0   0 my $self = shift;
424 0         0 $self->{$namespace} = {};
425 0         0 return 1;
426             }
427 0         0 }
428             sub _make_method_clear_arrayref {
429 0     0   0 my ($class,$name)= @_;
430              
431 0         0 my $namespace = "$class\::$name";
432 0         0 *{$namespace} = sub {
433 0     0   0 my $self = shift;
434 0         0 $self->{$namespace} = [];
435 0         0 return 1;
436             }
437 0         0 }
438              
439              
440              
441              
442             #use Smart::Comments '####';
443              
444             # _make_setget_unique_array()
445             sub _make_setget_unique_array {
446 3     3   9 my($_class, $_name, $_default_value) = @_;
447              
448             #### $_default_value
449             #### $_name
450              
451 3 100       14 if( defined $_default_value ){
452 1 50 33     10 ref $_default_value
453             and ref $_default_value eq 'ARRAY'
454             or confess("Default value to $_class '$_name' must be array ref");
455             }
456              
457 3         12 my $namespace = "$_class\::$_name";
458            
459 10     10   117 no strict 'refs';
  10         23  
  10         21863  
460              
461             # method name
462 3         8 my $method_name_href = "$_name\_href";
463 3         8 my $method_name_aref = "$_name\_aref";
464 3         8 my $method_name_count = "$_name\_count";
465 3         6 my $method_name_delete = "$_name\_delete";
466 3         8 my $method_name_add = "$_name\_add";
467 3         8 my $method_name_exists = "$_name\_exists";
468 3         9 my $method_name_clear = "$_name\_clear";
469              
470             # return array
471 3         21 *{"$_class\::$_name"} = sub {
472 4     4   659 my $self = shift;
473              
474 4         9 map{ $self->$method_name_href->{$_}++ } grep { defined $_ } @_;
  1         4  
  1         5  
475              
476 4         9 my @a = sort keys %{$self->$method_name_href};
  4         11  
477 4 100       26 wantarray ? @a : \@a;
478 3         24 };
479              
480             # return array ref
481 3         14 *{"$_class\::$method_name_aref"} = sub {
482 1     1   365 [ sort keys %{$_[0]->$method_name_href} ]
  1         5  
483 3         29 };
484              
485             # return count
486 3         16 *{"$_class\::$method_name_count"} = sub {
487 12     12   7546 scalar keys %{$_[0]->$method_name_href}
  12         35  
488 3         17 };
489              
490             # add
491 3         16 *{"$_class\::$method_name_add"} = sub {
492 9     9   1951 my $self = shift;
493 9         37 map{ $self->$method_name_href->{$_}++ } grep { defined $_ } @_;
  10         28  
  10         26  
494 9         41 1;
495 3         15 };
496              
497             # delete
498 3         16 *{"$_class\::$method_name_delete"} = sub {
499 9     9   997 my $self = shift;
500 9         21 map{ delete $self->$method_name_href->{$_} } grep { defined $_ } @_;
  11         25  
  11         28  
501 9         31 1;
502 3         31 };
503              
504             # exists
505 3         40 *{"$_class\::$method_name_exists"} = sub {
506 14     14   2244 my $self = shift;
507 14 100       45 exists $self->$method_name_href->{$_[0]} ? 1 : 0
508 3         15 };
509              
510             # clear
511 3         17 *{"$_class\::$method_name_clear"} = sub {
512 0     0   0 my $self = shift;
513 0         0 $self->{$method_name_href} = {};
514 0         0 1;
515 3         62 };
516              
517             # actual data holder..... the href.....
518              
519            
520            
521             # if the key does not exist and we DO have a default in the class...
522 3         25 *{"$_class\::$method_name_href"} = sub {
523 61     61   3378 my $self = shift;
524              
525 61 100       164 if ( ! exists $self->{$method_name_href} ){
526             #### apparently not init yet
527            
528 4 100       33 if ( exists $self->{$_name} ){
    100          
529             #### was in constructor
530 1 50 33     18 ref $self->{$_name}
531             and ref $self->{$_name} eq 'ARRAY'
532             or confess("value for $_class $_name must be array ref");
533              
534 1         2 @{$self->{$method_name_href}}{ @{$self->{$_name}} } = ();
  1         7  
  1         4  
535             }
536             elsif ( defined $_default_value ){ # was already checked for ARRAY ref
537             #### had default value
538 1         3 @{$self->{$method_name_href}}{ @$_default_value } = ();
  1         6  
539             }
540            
541             else {
542             #### blank value
543 2         7 $self->{$method_name_href} = {};
544             }
545             }
546 61         538 $self->{$method_name_href}
547 3         23 };
548              
549             }
550              
551              
552             #
553              
554              
555              
556              
557              
558             # TODO, check if subs exist alreaddy? can()
559             # should we do this or not?
560              
561              
562             # setget arrayref
563             sub _make_setget_aref {
564 6     6   12 my($_class, $_name, $_default_value) = @_;
565              
566 6         14 my $namespace = "$_class\::$_name";
567 6         12 my $namespace_count = "$_class\::$_name\_count";
568              
569 6         25 *{$namespace} = sub {
570 33     33   29146 my $self = shift;
571 33         46 my ($val) = @_;
572            
573 33 100       79 if( defined $val ){ # store it in object instance only
574             ### 343 VAL
575 2 50       16 ref $val eq 'ARRAY' or die("must be array ref arg");
576 2         17 $self->{$_name} = $val;
577             }
578              
579             # if the key does not exist and we DO have a default in the class...
580 33 100       80 if( !exists $self->{$_name}){
581              
582 5 100       10 if ( defined $_default_value ){
583             ### 350 DEF
584 3         8 $self->{$_name} = [ @$_default_value ];
585             }
586             else {
587             ### NON
588 2         5 $self->{$_name} = [];
589             }
590             }
591              
592 33 100       222 wantarray ? return @{$self->{$_name}} : return $self->{$_name};
  5         20  
593 6         24 };
594             #TODO, right now if undef, we set to [], is this teh behaviour we want?
595              
596 6         18 _make_count_for($_class, $_name);
597             }
598              
599              
600              
601              
602             sub _make_count_for {
603 8     8   15 my($class, $methodorkey) = @_;
604              
605 8         17 my $namespace = "$class\::$methodorkey\_count";
606              
607 8         52 *{$namespace} = sub {
608 21     21   3455 my $self = shift;
609              
610 21         28 my $thing;
611              
612             # object method?
613 21 100       93 if ($self->can($methodorkey)){
    50          
614 17         44 $thing = $self->$methodorkey;
615             }
616             # object key?
617             elsif( exists $self->{$methodorkey}){
618 4         7 $thing = $self->{$methodorkey};
619             }
620            
621             # die???, NO NO.. we do want to return if nothing.. if we want a method that just counts
622             # a value in the object instance, taht's all
623             else {
624 0         0 return 0; # ???
625             #die;
626             }
627              
628              
629             # ok... now what..
630 21         46 my $ref = ref $thing;
631 21 100 66     102 if( $ref and $ref eq 'ARRAY'){
    50 33        
632 19         80 return scalar @$thing;
633             }
634             elsif( $ref and $ref eq 'HASH'){
635 2         9 return scalar keys %$thing;
636             }
637             # else ???
638             # die??
639 0         0 return 0; # ???
640 8         87 };
641              
642             }
643              
644              
645             # BEGIN CONF
646              
647             sub make_conf {
648 2     2 1 9 my $class = shift;
649 2         3 my $default_path = shift; # can be undef
650              
651 2         5 _make_setget($class, 'abs_conf', $default_path);
652              
653 2         4 for my $name (qw(conf conf_load conf_save conf_keys)){
654             #$class->can($name) and warn("Class $class can already '$name()'");
655 8         15 *{"$class\::$name"} = \&$name;
  8         30  
656             }
657              
658              
659             sub conf {
660 5 100   5 0 21 $_[0]->{conf} or $_[0]->conf_load;
661 5   100     11963 $_[0]->{conf} ||= {};
662             }
663             sub conf_load {
664 3     3 0 938 require YAML;
665 3 50 0     7893 my $a = $_[0]->abs_conf
666             or warn "Can't load conf, missing abs_conf path."
667             and return;
668 3 100 50     86 -f $a
669             or warn "Can't load conf, not on disk '$a'\n"
670             and return;
671              
672 1         4 $_[0]->{conf} = YAML::LoadFile($a)
673             }
674 3 50   3 0 410 sub conf_keys { my $c = $_[0]->conf or return; sort keys %$c }
  3         33  
675 1     1 0 6 sub conf_save { require YAML; YAML::DumpFile($_[0]->abs_conf,$_[0]->{conf}) }
  1         26  
676              
677             }
678              
679              
680              
681              
682              
683              
684             # END CONF
685              
686              
687             1;