File Coverage

blib/lib/App/Framework/Lite/Object.pm
Criterion Covered Total %
statement 120 303 39.6
branch 41 128 32.0
condition 12 65 18.4
subroutine 20 43 46.5
pod 26 34 76.4
total 219 573 38.2


line stmt bran cond sub pod time code
1             package App::Framework::Lite::Object ;
2              
3             =head1 NAME
4              
5             Object - Basic object
6              
7             =head1 SYNOPSIS
8              
9             use App::Framework::Lite::Object ;
10              
11              
12             =head1 DESCRIPTION
13              
14              
15             =head1 DIAGNOSTICS
16              
17             Setting the debug flag to level 1 prints out (to STDOUT) some debug messages, setting it to level 2 prints out more verbose messages.
18              
19             =head1 AUTHOR
20              
21             Steve Price C<< >>
22              
23             =head1 BUGS
24              
25             None that I know of!
26              
27             =head1 INTERFACE
28              
29             =over 4
30              
31             =cut
32              
33 2     2   41323 use strict ;
  2         4  
  2         591  
34 2     2   12 use Carp ;
  2         5  
  2         132  
35 2     2   11 use Cwd ;
  2         13  
  2         5325  
36              
37             our $VERSION = "2.002" ;
38             our $AUTOLOAD ;
39              
40             #============================================================================================
41             # USES
42             #============================================================================================
43              
44              
45             #============================================================================================
46             # GLOBALS
47             #============================================================================================
48             my $global_debug = 0 ;
49             my $global_verbose = 0 ;
50             my $strict_fields = 0 ;
51              
52             my @SPECIAL_FIELDS = qw/
53             global_debug
54             global_verbose
55             strict_fields
56             / ;
57              
58             my %COMMON_FIELDS = (
59             'debug' => undef, # pseudo field
60             'verbose' => undef, # pseudo field
61             ) ;
62              
63             # Constant
64             #my @REQ_LIST ;
65             my %FIELD_LIST ;
66              
67             my %CLASS_INIT;
68             my %CLASS_INSTANCE ;
69              
70             my %DEBUG ;
71             my %VERBOSE ;
72              
73             #============================================================================================
74             # CONSTRUCTOR
75             #============================================================================================
76              
77             =item B
78              
79             Create a new object.
80              
81             The %args are specified as they would be in the B method, for example:
82              
83             'mmap_handler' => $mmap_handler
84              
85             Special arguments are:
86              
87             'fields' => Either ARRAY list of valid field names, or HASH of field names with default values
88              
89             Example:
90              
91             new(
92             'fields' => {
93             'cmd' => undef,
94             'status' => 0,
95             'results' => [],
96            
97             )
98             )
99              
100             All defined fields have an accessor method created.
101              
102             =cut
103              
104             sub new
105             {
106 2     2 1 301 my ($obj, %args) = @_ ;
107              
108 2   33     15 my $class = ref($obj) || $obj ;
109             #my $class = $obj->class() ;
110              
111 2 50       7 print "== Object: Creating new $class object ========\n" if $global_debug ;
112             # prt_data("ARGS=", \%args, "\n") if $global_debug>=2 ;
113              
114             # Initialise class variables
115 2         14 $class->init_class(%args);
116              
117             # Create object
118 2         5 my $this = {} ;
119 2         5 bless ($this, $class) ;
120              
121             # Initialise object
122 2         11 $this->init(%args) ;
123              
124             # # Check for required settings
125             # foreach (@REQ_LIST)
126             # {
127             # do
128             # {
129             # croak "ERROR: $class : Must specify setting for $_" ;
130             # } unless defined($this->{$_}) ;
131             # }
132              
133             # prt_data("== Created object=", $this, "================================================\n") if $global_debug ;
134            
135 2         5 return($this) ;
136             }
137              
138             #-----------------------------------------------------------------------------
139              
140             =item B
141              
142             Initialises the newly created object instance.
143              
144              
145             =cut
146              
147             sub init
148             {
149 2     2 1 4 my $this = shift ;
150 2         4 my (%args) = @_ ;
151              
152             # prt_data("init() ARGS=", \%args, "\n") if $global_debug>=3 ;
153              
154             #my $class = $this->class() ;
155             ##my $class = ref($this) || $this ;
156 2         8 $this = $this->check_instance() ;
157            
158             # Defaults
159             ## my %field_list = $this->field_list() ;
160 2   33     6 my $class = ref($this) || $this ;
161 2         13 my %field_list = ();
162 2 50       7 %field_list = %{ $FIELD_LIST{$class} } if exists($FIELD_LIST{$class}) ;
  2         9  
163            
164              
165             # May have default value for some or all fields
166 2         3 my %field_copy ;
167 2         5 foreach my $fld (keys %field_list)
168             {
169 12         12 my $val = $field_list{$fld} ;
170            
171             # If value is an ARRAY ref or a HASH ref then we want a new copy of this per instance (otherwise
172             # all instances will have a ref to the same HASH/ARRAY and one instance will change all instance's values!)
173 12 100       29 if (ref($val) eq 'ARRAY')
    100          
174             {
175 2         3 $val = [@$val] ;
176             }
177             elsif (ref($val) eq 'HASH')
178             {
179 2         2 $val = { (%$val) } ;
180             }
181            
182 12         19 $field_copy{$fld} = $val ;
183             }
184              
185 2         13 $this->set(%field_copy) ;
186              
187             ## Handle special fields
188 2         5 foreach my $special (@SPECIAL_FIELDS)
189             {
190 6 50       13 if (exists($args{$special}))
191             {
192             # remove from args list
193 0         0 my $special_val = delete $args{$special} ;
194            
195             # call variable handler
196 0         0 $this->$special($special_val) ;
197             }
198             }
199              
200             ## Set fields from parameters
201 2         6 $this->set(%args) ;
202              
203 2 50       8 print "init() - done\n" if $global_debug>=3 ;
204              
205             }
206              
207             #-----------------------------------------------------------------------------
208              
209             =item B
210              
211             Initialises the object class variables.
212              
213              
214             =cut
215              
216             sub init_class
217             {
218 2     2 1 47 my $this = shift ;
219 2         6 my (%args) = @_ ;
220              
221             #my $class = $this->class() ;
222 2   33     11 my $class = ref($this) || $this ;
223              
224             # prt_data("init_class() ARGS=", \%args, "\n") if $global_debug>=3 ;
225             #prt_data("init_class() ARGS (LIST)=", \@_, "\n") ;
226              
227 2 100       8 if (!$CLASS_INIT{$class})
228             {
229             # Field list
230 1         3 $FIELD_LIST{$class} = {};
231 1         5 my $fields = delete($args{'fields'}) ;
232              
233             # prt_data(" + fields=$fields", $fields, "ARGS=", \%args, "\n") if $global_debug>=4 ;
234             #prt_data(" init_class($class) FIELDS=", $fields, "\n") ;
235              
236 1 50       4 if ($fields)
237             {
238 1 50       5 print " + fields=$fields ref()=", ref($fields), "\n" if $global_debug>=4 ;
239              
240 1         2 my $class_fields_href = {} ;
241            
242             ## Do the fields
243 1 50       23 if (ref($fields) eq 'ARRAY')
    50          
244             {
245 0         0 $class_fields_href = {
246             (%COMMON_FIELDS),
247 0         0 map {$_ => undef} @$fields
248             } ;
249             }
250             elsif (ref($fields) eq 'HASH')
251             {
252 1         10 $class_fields_href = {
253             (%COMMON_FIELDS),
254             (%$fields)
255             } ;
256             }
257             else
258             {
259 0         0 $class_fields_href = {
260             (%COMMON_FIELDS),
261             ($fields => undef)
262             } ;
263             }
264            
265 1         4 $FIELD_LIST{$class} = $class_fields_href ;
266             }
267              
268             # create accessors
269 1         3 my $code = "package $class;\n" ;
270 1         3 foreach my $field (keys %{$FIELD_LIST{$class}})
  1         5  
271             {
272 6 100       57 if (!$class->can($field))
273             {
274 4         14 $code .= qq{
275             ## get / set
276             sub $field
277             {
278             my \$this = shift ;
279             \@_ ? \$this->{$field} = \$_[0] # set
280             : \$this->{$field}; # get
281             }
282             };
283             }
284            
285 6 100       74 if (!$class->can("undef_$field"))
286             {
287 4         23 $code .= qq{
288             ## undefine
289             sub undef_$field
290             {
291             my \$this = shift ;
292            
293             \$this->{$field} = undef ;
294             }
295             };
296             }
297             }
298            
299 1 50       5 print "Created Accessors:\n$code\n" if $global_debug>=4 ;
300            
301 1 100   9 0 402 eval $code;
  9 100   9 0 2064  
  9 100   6 0 32  
  9 100   9 0 1830  
  9     0 0 33  
  6     0 0 2470  
  6     3 0 31  
  9     0 0 2380  
  9         34  
  0         0  
  0         0  
  0         0  
  0         0  
  3         5  
  3         14  
  0         0  
  0         0  
302 1 50       6 if ($@) {
303 0         0 die "ERROR defining accessors for '$class':"
304             . "\n\t$@\n"
305             . "-----------------------------------------------------\n"
306             . $code;
307             }
308              
309             ## Create private fields
310            
311             #prt_data(" init_class: class=$class FIELD_LIST=", \%FIELD_LIST) if $global_debug>=4 ;
312              
313             # Finished
314 1         3 $CLASS_INIT{$class}=1;
315             }
316              
317 2 50       12 print "init_class() - done\n" if $global_debug>=3 ;
318             }
319              
320             #-----------------------------------------------------------------------------
321              
322             =item B
323              
324             Adds the contents of the HASH ref $fields_href to the args HASH ref ($args_href) under the key
325             'fields'. Used by derived objects to add their fields to the parent object's fields.
326              
327              
328             =cut
329              
330             sub add_fields
331             {
332 0     0 1 0 my $this = shift ;
333 0         0 my ($fields_href, $args_href) = @_ ;
334              
335             # Add extra fields
336 0         0 foreach (keys %$fields_href)
337             {
338 0         0 $args_href->{'fields'}{$_} = $fields_href->{$_} ;
339             }
340              
341             }
342              
343             #-----------------------------------------------------------------------------
344              
345             =item B
346              
347             Initialises the object class variables. Creates a class instance so that these
348             methods can also be called via the class (don't need a specific instance)
349              
350             =cut
351              
352             sub init_class_instance
353             {
354 0     0 1 0 my $class = shift ;
355 0         0 my (%args) = @_ ;
356              
357 0         0 $class->init_class(%args) ;
358              
359             # Create a class instance object - allows these methods to be called via class
360 0         0 $class->class_instance(%args) ;
361            
362             # Set any global values
363 0         0 $class->set(%args) ;
364             }
365              
366             #----------------------------------------------------------------------------
367             # Return global fields hash
368             sub _field_list
369             {
370 0     0   0 my $class = shift ;
371              
372 0         0 return %FIELD_LIST ;
373             }
374              
375             #============================================================================================
376             # CLASS METHODS
377             #============================================================================================
378              
379             #----------------------------------------------------------------------------
380              
381             =item B
382              
383             Set global debug print options to I.
384              
385             0 = No debug
386             1 = standard debug information
387             2 = verbose debug information
388              
389             =cut
390              
391             sub global_debug
392             {
393 0     0 1 0 my $this = shift ;
394 0         0 my ($flag) = @_ ;
395              
396             #my $class = $this->class() ;
397             ##my $class = ref($this) || $this ;
398              
399 0         0 my $old = $global_debug ;
400 0 0       0 $global_debug = $flag if defined($flag) ;
401              
402 0         0 return $old ;
403             }
404              
405              
406             #----------------------------------------------------------------------------
407              
408             =item B
409              
410             Set global verbose print level to I.
411              
412             0 = None verbose
413             1 = verbose information
414             2 = print commands
415             3 = print command results
416              
417             =cut
418              
419             sub global_verbose
420             {
421 0     0 1 0 my $this = shift ;
422 0         0 my ($flag) = @_ ;
423              
424             #my $class = $this->class() ;
425             ##my $class = ref($this) || $this ;
426              
427 0         0 my $old = $global_verbose ;
428 0 0       0 $global_verbose = $flag if defined($flag) ;
429              
430 0         0 return $old ;
431             }
432              
433             #----------------------------------------------------------------------------
434              
435             =item B
436              
437             Enable/disable strict field checking
438              
439             =cut
440              
441             sub strict_fields
442             {
443 0     0 1 0 my $this = shift ;
444 0         0 my ($flag) = @_ ;
445              
446             #my $class = $this->class() ;
447             ##my $class = ref($this) || $this ;
448              
449 0         0 my $old = $strict_fields ;
450 0 0       0 $strict_fields = $flag if defined($flag) ;
451              
452 0         0 return $old ;
453             }
454              
455             #----------------------------------------------------------------------------
456              
457             =item B
458              
459             Returns an object that can be used for class-based calls - object contains
460             all the usual fields
461            
462             =cut
463              
464             sub class_instance
465             {
466 2     2 1 60 my $this = shift ;
467 2         5 my (@args) = @_ ;
468              
469             #my $class = $this->class() ;
470 2   33     12 my $class = ref($this) || $this ;
471              
472 2 100 66     12 if ($class->allowed_class_instance() && !$class->has_class_instance())
473             {
474 1         3 $CLASS_INSTANCE{$class} = 1 ; # ensure we don't get here again (breaks recursive loop)
475              
476 1 50       4 print "-- Create class instance --\n" if $global_debug>=3 ;
477            
478             # Need to create one using the args
479 1         1132 $CLASS_INSTANCE{$class} = $class->new(@args) ;
480             }
481              
482              
483 2         10 return $CLASS_INSTANCE{$class} ;
484             }
485              
486             #----------------------------------------------------------------------------
487              
488             =item B
489              
490             Returns true if this class has a class instance object
491            
492             =cut
493              
494             sub has_class_instance
495             {
496 2     2 1 2 my $this = shift ;
497             #my $class = $this->class() ;
498 2   33     10 my $class = ref($this) || $this ;
499              
500             #prt_data("has_class_instance($class) CLASS_INSTANCE=", \%CLASS_INSTANCE) if $global_debug>=5 ;
501              
502 2         13 return exists($CLASS_INSTANCE{$class}) ;
503             }
504              
505             #----------------------------------------------------------------------------
506              
507             =item B
508              
509             Returns true if this class can have a class instance object
510            
511             =cut
512              
513             sub allowed_class_instance
514             {
515 2     2 1 15 return 1 ;
516             }
517              
518             #----------------------------------------------------------------------------
519              
520             =item B
521              
522             Returns hash of object's field definitions.
523              
524             =cut
525              
526             sub field_list
527             {
528 0     0 1 0 my $this = shift ;
529              
530             #my $class = $this->class() ;
531 0   0     0 my $class = ref($this) || $this ;
532            
533 0         0 my $href ;
534 0 0       0 $href = $FIELD_LIST{$class} if exists($FIELD_LIST{$class}) ;
535              
536 0 0       0 return $href ? %$href : () ;
537             }
538              
539              
540             #============================================================================================
541             # OBJECT DATA METHODS
542             #============================================================================================
543              
544             #----------------------------------------------------------------------------
545              
546             =item B
547              
548             Set debug print options to I.
549              
550              
551             =cut
552              
553             sub debug
554             {
555 0     0 1 0 my $this = shift ;
556 0         0 my ($level) = @_ ;
557              
558             #my $class = $this->class() ;
559 0   0     0 my $class = ref($this) || $this ;
560             #print "In debug() for $class\n" ;
561              
562 0   0     0 $DEBUG{$class} ||= 0 ;
563 0         0 my $old = $DEBUG{$class} ;
564 0 0       0 $DEBUG{$class} = $level if defined($level) ;
565              
566 0         0 return $old ;
567             }
568              
569             #----------------------------------------------------------------------------
570              
571             =item B
572              
573             Set debug print options flag to undefined.
574              
575              
576             =cut
577              
578             sub undef_debug
579             {
580 2     2 1 3 my $this = shift ;
581 2         2 my ($level) = @_ ;
582              
583             #my $class = $this->class() ;
584 2   33     6 my $class = ref($this) || $this ;
585             #print "In undef_debug() for $class\n" ;
586              
587 2   50     8 $DEBUG{$class} ||= 0 ;
588 2         3 my $old = $DEBUG{$class} ;
589 2         3 $DEBUG{$class} = undef ;
590              
591 2         4 return $old ;
592             }
593              
594              
595             #----------------------------------------------------------------------------
596              
597             =item B
598              
599             Set verbose print options to I.
600              
601              
602             =cut
603              
604             sub verbose
605             {
606 0     0 1 0 my $this = shift ;
607 0         0 my ($level) = @_ ;
608              
609             #my $class = $this->class() ;
610 0   0     0 my $class = ref($this) || $this ;
611             #print "In verbose() for $class\n" ;
612              
613 0   0     0 $VERBOSE{$class} ||= 0 ;
614 0         0 my $old = $VERBOSE{$class} ;
615 0 0       0 $VERBOSE{$class} = $level if defined($level) ;
616              
617 0         0 return $old ;
618             }
619              
620             #----------------------------------------------------------------------------
621              
622             =item B
623              
624             Set verbose print options flag to undefined.
625              
626              
627             =cut
628              
629             sub undef_verbose
630             {
631 2     2 1 3 my $this = shift ;
632 2         2 my ($level) = @_ ;
633              
634             #my $class = $this->class() ;
635 2   33     6 my $class = ref($this) || $this ;
636             #print "In undef_verbose() for $class\n" ;
637              
638 2   50     7 $DEBUG{$class} ||= 0 ;
639 2         4 my $old = $DEBUG{$class} ;
640 2         2 $DEBUG{$class} = undef ;
641              
642 2         4 return $old ;
643             }
644              
645             #----------------------------------------------------------------------------
646              
647             =item B
648              
649             Get/set a field value. Used by derived objects to get/set the underlying object field
650             variable when they have overridden that field's access method.
651              
652             =cut
653              
654             sub field_access
655             {
656 0     0 1 0 my $this = shift ;
657 0         0 my ($field, $value) = @_ ;
658              
659 0   0     0 my $class = ref($this) || $this ;
660 0         0 my %field_list = ();
661 0 0       0 %field_list = %{ $FIELD_LIST{$class} } if exists($FIELD_LIST{$class}) ;
  0         0  
662 0 0       0 $this->throw_fatal("Attempting to access an invalid field \"$field\" for this object class \"$class\" ") unless (exists($field_list{$field})) ;
663              
664 0 0       0 $this->{$field} = $value if defined($value) ;
665 0         0 return $this->{$field} ;
666             }
667              
668              
669              
670              
671              
672             #----------------------------------------------------------------------------
673              
674             =item B
675              
676             Set one or more settable parameter.
677              
678             The %args are specified as a hash, for example
679              
680             set('mmap_handler' => $mmap_handler)
681              
682             Sets field values. Field values are expressed as part of the HASH (i.e. normal
683             field => value pairs).
684              
685             =cut
686              
687             sub set
688             {
689 6     6 1 1287 my $this = shift ;
690 6         16 my (%args) = @_ ;
691              
692             # prt_data("set() ARGS=", \%args, "\n") if $global_debug>=3 ;
693              
694 6         12 $this = $this->check_instance() ;
695            
696             # Args
697             ## my %field_list = $this->field_list() ;
698 6   33     17 my $class = ref($this) || $this ;
699 6         7 my %field_list = ();
700 6 50       15 %field_list = %{ $FIELD_LIST{$class} } if exists($FIELD_LIST{$class}) ;
  6         32  
701              
702 6         16 foreach my $field (keys %field_list)
703             {
704 36 100       108 if (exists($args{$field}))
705             {
706 20 50       38 print " + set $field = $args{$field}\n" if $global_debug>=3 ;
707              
708             # Need to call actual method (rather than ___set) so that it can be overridden
709 20 100       42 if (!defined($args{$field}))
710             {
711             # Set to undef
712 7         12 my $undef_method = "undef_$field" ;
713 7         106 $this->$undef_method() ;
714             }
715             else
716             {
717 13         339 $this->$field($args{$field}) ;
718             }
719             }
720             }
721              
722             ## See if strict checks are enabled
723 6 50       14 if ($strict_fields)
724             {
725             # Check to ensure that only the valid fields are being set
726 0         0 foreach my $field (keys %args)
727             {
728 0 0       0 if (!exists($field_list{$field}))
729             {
730 0         0 print "WARNING::Attempt to set invalid field \"$field\" \n" ;
731 0         0 $this->dump_callstack() ;
732             }
733             }
734             }
735            
736 6 50       24 print "set() - done\n" if $global_debug>=3 ;
737              
738             }
739              
740             #----------------------------------------------------------------------------
741              
742             =item B
743              
744             Returns hash of object's fields (i.e. field name => field value pairs).
745              
746             If @names array is specified, then only returns the HASH containing the named fields.
747              
748             =cut
749              
750             sub vars
751             {
752 0     0 1 0 my $this = shift ;
753 0         0 my (@names) = @_ ;
754              
755             ## my %field_list = $this->field_list() ;
756 0   0     0 my $class = ref($this) || $this ;
757 0         0 my %field_list = ();
758 0 0       0 %field_list = %{ $FIELD_LIST{$class} } if exists($FIELD_LIST{$class}) ;
  0         0  
759              
760 0         0 my %fields ;
761              
762             #prt_data("vars() names=", \@names) ;
763            
764             # If no names specified then get all of them
765 0 0       0 unless (@names)
766             {
767 0         0 @names = keys %field_list ;
768             }
769 0         0 my %names = map {$_ => 1} @names ;
  0         0  
770             #prt_data(" + names=", \%names) ;
771            
772             # Get the value of each field
773 0         0 foreach my $field (keys %field_list)
774             {
775             # Store field if we've asked for it
776 0 0       0 $fields{$field} = $this->$field() if exists($names{$field}) ;
777             #print " + + $field : " ;
778             #if (exists($fields{$field}))
779             #{
780             # print "ok ($fields{$field})\n" ;
781             #}
782             #else
783             #{
784             # print "not wanted\n" ;
785             #}
786             }
787            
788 0         0 return %fields ;
789             }
790              
791              
792              
793              
794             #----------------------------------------------------------------------------
795              
796             =item B
797              
798             Destroy object
799              
800             =cut
801              
802             sub DESTROY
803             {
804 1     1   689 my $this = shift ;
805              
806             }
807              
808              
809             #============================================================================================
810             # OBJECT METHODS
811             #============================================================================================
812              
813             #----------------------------------------------------------------------------
814              
815             =item B
816              
817             If this is not an instance (i.e. a class call), then if there is a class_instance
818             defined use it, otherwise error.
819              
820             =cut
821              
822             sub check_instance
823             {
824 8     8 1 11 my $this = shift ;
825 8         12 my (%args) = @_ ;
826              
827             #my $class = $this->class() ;
828            
829 8 50       17 if (!ref($this))
830             {
831 0   0     0 my $class = ref($this) || $this ;
832 0 0       0 if ($class->has_class_instance())
833             {
834 0         0 $this = $class->class_instance() ;
835             }
836             else
837             {
838 0         0 croak "$this is not a usable object" ;
839             }
840             }
841              
842 8         29 return $this ;
843             }
844              
845              
846             #----------------------------------------------------------------------------
847              
848             =item B
849              
850             Transfers all the supported attributes from $this object to $target object.
851              
852             =cut
853              
854             sub copy_attributes
855             {
856 0     0 1   my $this = shift ;
857 0           my ($target) = @_ ;
858              
859 0           $this = $this->check_instance() ;
860 0           $target = $target->check_instance() ;
861            
862             # Get list of fields in the target
863 0           my %target_field_list = $target->field_list() ;
864            
865             # Copy values from this object
866 0           my %field_list = $this->field_list() ;
867 0           foreach my $field (keys %target_field_list)
868             {
869             # see if can copy
870 0 0         if (exists($field_list{$field}))
871             {
872 0           $target->set($field => $this->$field()) ;
873             }
874             }
875            
876             }
877              
878             #----------------------------------------------------------------------------
879              
880             =item B
881              
882             Returns name of object class.
883              
884             =cut
885              
886             sub class
887             {
888 0     0 1   my $this = shift ;
889              
890 0   0       my $class = ref($this) || $this ;
891            
892 0           return $class ;
893             }
894              
895             #----------------------------------------------------------------------------
896              
897             =item B
898              
899             Create a copy of this object and return the copy.
900              
901             =cut
902              
903             sub clone
904             {
905 0     0 1   my $this = shift ;
906              
907 0           my $clone ;
908            
909             # TODO: WRITE IT!
910            
911 0           return $clone ;
912             }
913              
914              
915              
916             # ============================================================================================
917             # UTILITY METHODS
918             # ============================================================================================
919              
920              
921              
922             #----------------------------------------------------------------------------
923              
924             =item B
925              
926             Returns a quoted version of the string.
927            
928             =cut
929              
930             sub quote_str
931             {
932 0     0 1   my $this = shift ;
933 0           my ($str) = @_ ;
934            
935             ##my $class = $this->class() ;
936              
937             # skip on Windows machines
938 0 0         unless ($^O eq 'MSWin32')
939             {
940             # first escape any existing quotes
941 0           $str =~ s%\\'%'%g ;
942 0           $str =~ s%'%'\\''%g ;
943            
944 0           $str = "'".$str."'" ;
945             }
946            
947            
948 0           return $str ;
949             }
950              
951             #----------------------------------------------------------------------------
952              
953             =item B
954              
955             Work through string expanding any variables, replacing them with the value stored in the %vars hash.
956             If variable is not stored in %vars, then that variable is left.
957              
958             Returns expanded string.
959              
960             =cut
961              
962             sub expand_vars
963             {
964 0     0 1   my $this = shift ;
965 0           my ($string, $vars_href) = @_ ;
966              
967              
968             # Do replacement
969 0           $string =~ s{
970             \$ # find a literal dollar sign
971             \{{0,1} # optional brace
972             (\w+) # find a "word" and store it in $1
973             \}{0,1} # optional brace
974             }{
975 2     2   26 no strict 'refs'; # for $$1 below
  2         4  
  2         1893  
976 0 0         if (defined $vars_href->{$1}) {
977 0           $vars_href->{$1}; # expand variable
978             } else {
979 0           "\${$1}"; # leave it
980             }
981             }egx;
982              
983 0           return $string ;
984             }
985              
986              
987              
988             ##---------------------------------------------------------------------
989             #
990             #=item B
991             #
992             #Use App::Framework::Lite::Object::DumpObj to print out variable information. Automatically enables
993             #object print out
994             #
995             #=cut
996             #
997             #sub prt_data
998             #{
999             # my $this = shift ;
1000             # my (@args) = @_ ;
1001             #
1002             # App::Framework::Lite::Object::DumpObj::print_objects_flag(1) ;
1003             # App::Framework::Lite::Object::DumpObj::prt_data(@args) ;
1004             #}
1005             #
1006             ##----------------------------------------------------------------------------
1007             ##
1008             ##=item B<_dbg_prt($items_aref [, $min_debug])>
1009             ##
1010             ##Print out the items in the $items_aref ARRAY ref iff the calling object's debug level is >0.
1011             ##If $min_debug is specified, will only print out items if the calling object's debug level is >= $min_debug.
1012             ##
1013             ##=cut
1014             ##
1015             #sub _dbg_prt
1016             #{
1017             # my $obj = shift ;
1018             # my ($items_aref, $min_debug) = @_ ;
1019             #
1020             # $min_debug ||= 1 ;
1021             #
1022             # ## check debug level setting
1023             # if ($obj->debug >= $min_debug)
1024             # {
1025             # my $pkg = ref($obj) ;
1026             # $pkg =~ s/App::Framework/ApFw/ ;
1027             #
1028             # my $prefix = App::Framework::Lite::Object::DumpObj::prefix("$pkg :: ") ;
1029             # $obj->prt_data(@$items_aref) ;
1030             # App::Framework::Lite::Object::DumpObj::prefix($prefix) ;
1031             # }
1032             #}
1033              
1034              
1035              
1036             #---------------------------------------------------------------------
1037              
1038             =item B
1039              
1040             Print out the call stack. Useful for debug output at a crash site.
1041             =cut
1042              
1043             sub dump_callstack
1044             {
1045 0     0 1   my $this = shift ;
1046 0           my ($package, $filename, $line, $subr, $has_args, $wantarray) ;
1047 0           my $i=0 ;
1048 0           print "\n-----------------------------------------\n";
1049             do
1050 0           {
1051 0           ($package, $filename, $line, $subr, $has_args, $wantarray) = caller($i++) ;
1052 0 0         if ($subr)
1053             {
1054 0           print "$filename :: $subr :: $line\n" ;
1055             }
1056             }
1057             while($subr) ;
1058 0           print "-----------------------------------------\n\n";
1059             }
1060              
1061              
1062              
1063             # ============================================================================================
1064             # PRIVATE METHODS
1065             # ============================================================================================
1066              
1067             #----------------------------------------------------------------------------
1068             # Set field value
1069             sub ___set
1070             {
1071 0     0     my $this = shift ;
1072 0           my ($field, $new_value) = @_ ;
1073              
1074             ## NEW
1075 0 0         if ($global_debug>=10)
1076             {
1077 0           print "Unexpected ___set($field, $new_value)\n" ;
1078 0           $this->dump_callstack() ;
1079             }
1080             ## NEW
1081              
1082              
1083             #my $class = $this->class() ;
1084 0           my $value ;
1085              
1086             # Check that field name is valid
1087             ## my %field_list = $this->field_list() ;
1088 0   0       my $class = ref($this) || $this ;
1089 0           my %field_list = ();
1090 0 0         %field_list = %{ $FIELD_LIST{$class} } if exists($FIELD_LIST{$class}) ;
  0            
1091              
1092 0 0         if (!exists($field_list{$field}))
1093             {
1094             ## my $class = ref($this) || $this ;
1095              
1096             # prt_data("$class : ___set($field) invalid field. Valid fields=", \%field_list) if $global_debug>=5 ;
1097 0 0         $this->dump_callstack() if $global_debug>=10 ;
1098              
1099             # TODO: Do something more useful!
1100 0           croak "$class: Attempting to write invalid field $field" ;
1101             }
1102             else
1103             {
1104             # get existing value
1105 0           $value = $this->{$field} ;
1106            
1107             # write
1108 0           $this->{$field} = $new_value ;
1109             }
1110 0 0         print " + ___set($field) <= $new_value (was $value)\n" if $global_debug>=5 ;
1111              
1112             # Return previous value
1113 0           return $value ;
1114             }
1115              
1116             #----------------------------------------------------------------------------
1117             # get field value
1118             sub ___get
1119             {
1120 0     0     my $this = shift ;
1121 0           my ($field) = @_ ;
1122              
1123 0           my $value ;
1124            
1125             #my $class = $this->class() ;
1126              
1127             ## NEW
1128 0 0         if ($global_debug>=10)
1129             {
1130 0           print "Unexpected ___get($field)\n" ;
1131 0           $this->dump_callstack() ;
1132             }
1133             ## NEW
1134              
1135              
1136             # Check that field name is valid
1137             ## my %field_list = $this->field_list() ;
1138 0   0       my $class = ref($this) || $this ;
1139 0           my %field_list = ();
1140 0 0         %field_list = %{ $FIELD_LIST{$class} } if exists($FIELD_LIST{$class}) ;
  0            
1141              
1142 0 0         if (!exists($field_list{$field}))
1143             {
1144             ## my $class = ref($this) || $this ;
1145              
1146             # prt_data("$class : ___get($field) invalid field. Valid fields=", \%field_list) if $global_debug>=5 ;
1147             #prt_data("$class : ___get($field) invalid field. Valid fields=", \%field_list) ;
1148 0 0         $this->dump_callstack() if $global_debug>=10 ;
1149             #$this->dump_callstack() ;
1150              
1151             # TODO: Do something more useful!
1152 0           croak "$class: Attempting to access invalid method $field (or read using invalid data accessor)" ;
1153             }
1154             else
1155             {
1156             # get existing value
1157 0           $value = $this->{$field} ;
1158             }
1159              
1160 0 0         print " + ___get($field) = $value\n" if $global_debug>=5 ;
1161              
1162             # Return previous value
1163 0           return $value ;
1164             }
1165              
1166              
1167             # ============================================================================================
1168              
1169             # Autoload handle only field value set/undefine
1170             # Set method =
1171             # Undefine method = undef_
1172             #
1173             sub AUTOLOAD
1174             {
1175 0 0   0     print "AUTOLOAD ($AUTOLOAD)\n" if $global_debug>=5 ;
1176              
1177             ## NEW
1178 0 0         if ($global_debug>=10)
1179             {
1180 0           my $caller = (caller())[0] ;
1181 0           print "Unexpected AUTOLOAD ($AUTOLOAD) from $caller\n" ;
1182             }
1183             ## NEW
1184              
1185 0           my $this = shift;
1186             # prt_data("AUTOLOAD ($AUTOLOAD) this=", $this) if $global_debug>=5 ;
1187              
1188             #print "$this=",ref($this),"\n";
1189 0 0 0       if (!ref($this)||ref($this)eq'ARRAY')
1190             {
1191 0           croak "AUTOLOAD ($AUTOLOAD) (@_): $this is not a valid object" ;
1192             }
1193              
1194 0           $this = $this->check_instance() ;
1195             # prt_data(" + this=", $this) if $global_debug>=5 ;
1196              
1197 0           my $name = $AUTOLOAD;
1198 0           $name =~ s/.*://; # strip fully-qualified portion
1199 0           my $class = $AUTOLOAD;
1200 0           $class =~ s/::[^:]+$//; # get class
1201              
1202 0           my $type = ref($this) ;
1203            
1204             # if (!$type)
1205             # {
1206             # # see if there is a class instance object defined
1207             # if ($class->has_class_instance())
1208             # {
1209             # $this = $class->class_instance() ;
1210             # $type = ref($this) ;
1211             # }
1212             # else
1213             # {
1214             # croak "$this is not an object";
1215             # }
1216             # }
1217              
1218             # possibly going to set a new value
1219 0           my $set=0;
1220 0           my $new_value = shift;
1221 0 0         $set = 1 if defined($new_value) ;
1222            
1223             # 1st see if this is of the form undef_
1224 0 0         if ($name =~ m/^undef_(\w+)$/)
1225             {
1226 0           $set = 1 ;
1227 0           $name = $1 ;
1228 0           $new_value = undef ;
1229             }
1230              
1231 0           my $value = $this->___get($name);
1232              
1233 0 0         if ($set)
1234             {
1235 0           $this->___set($name, $new_value) ;
1236             }
1237              
1238             # Return previous value
1239 0           return $value ;
1240             }
1241              
1242              
1243              
1244             # ============================================================================================
1245             # END OF PACKAGE
1246             1;
1247              
1248             __END__