File Coverage

blib/lib/POEIKC/Daemon/Utility.pm
Criterion Covered Total %
statement 33 428 7.7
branch 0 196 0.0
condition 0 62 0.0
subroutine 11 50 22.0
pod 0 30 0.0
total 44 766 5.7


line stmt bran cond sub pod time code
1             package POEIKC::Daemon::Utility;
2              
3 1     1   8 use strict;
  1         1  
  1         42  
4 1     1   22 use 5.008_001;
  1         19  
  1         45  
5              
6 1     1   6 use warnings;
  1         2  
  1         31  
7 1     1   5 use Data::Dumper ();
  1         2  
  1         22  
8              
9 1     1   5 use Class::Inspector;
  1         3  
  1         11  
10 1     1   30 use UNIVERSAL::require;
  1         3  
  1         7  
11 1     1   28 use POE::Sugar::Args;
  1         3  
  1         8  
12              
13             our $DEBUG;
14              
15             sub DEBUG {
16 0     0 0   my $self = shift;
17 0 0         $DEBUG = shift if @_;;
18             }
19              
20             sub _new {
21 0     0     my $class = shift ;
22 0           my $self = {
23             @_
24             };
25 0 0         $class = ref $class if ref $class;
26 0           bless $self,$class ;
27 0           return $self ;
28             }
29              
30              
31 0     0 0   sub inc {shift->{inc}}
32 0     0 0   sub state_list {shift->{state_list}}
33              
34             sub _init {
35 0     0     my $self = shift;
36 0           $self->{inc} = {};
37 0           $self->{state_list} = {};
38             }
39              
40              
41              
42             sub shutdown {
43 0     0 0   my $self = shift;
44 0           my %args = @_;
45 0           my ($poe, $rsvp, $from, $args) = (
46             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
47 0           my ($alias, $event_ary) = ($args{alias}, $args{event});
48              
49 0           $poe->kernel->yield('shutdown');
50 0           return sprintf("%s PID:%s ... stopped!! (%s)\n", $0, $$, scalar(localtime));
51             }
52              
53             ### loop, relay, chain vvvvvvvvvvvvvvvvvvvvvvvvv
54             package POEIKC::Daemon::State;
55              
56 1     1   487 use base qw/Class::Accessor::Fast/;
  1         2  
  1         1074  
57              
58             __PACKAGE__->mk_accessors(qw/event_name next_mthod destination module method module_delay/);
59              
60             sub new {
61 0     0     my $class = shift ;
62 0           my %args = @_;
63 0           my $self = $class->SUPER::new(\%args);
64 0           $self->{limit} = $args{limit};
65 0           return $self ;
66             }
67              
68              
69             package POEIKC::Daemon::Utility;
70              
71              
72             sub stop{
73 0     0 0   my $self = shift;
74 0           my %args = @_;
75 0           my ($poe, $rsvp, $from, $args) = (
76             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
77 0           my $kernel = $poe->kernel;
78 0 0         my ($something, $method, @args) = @{$args} if ref $args eq 'ARRAY';
  0            
79 0   0       $something ||= $args{something};
80              
81 0 0         $self->state_list->{$something} or return;
82              
83 0 0         if (ref $self->state_list->{$something} eq 'HASH') {
84 0           my $event_name = $self->state_list->{$something}->event_name;
85 0 0         $DEBUG and _DEBUG_log( $event_name, $something);
86 0           $kernel->state( $event_name );
87 0 0         if ($method) {
88 0           my $destination = $self->state_list->{$something}->destination;
89 0           my $module = $self->state_list->{$something}->module;
90 0 0         $DEBUG and _DEBUG_log($self->state_list->{$something}, $event_name, $something, $destination, $module, $method, @args);
91 0 0         $DEBUG and _DEBUG_log($destination, $module, $method, @args);
92 0           return $self->execute(poe=>$poe, from=>$destination, module=>$module, method=>$method, args=>\@args);
93             }
94 0           delete $self->state_list->{$something};
95 0           return $event_name;
96             }
97             }
98              
99              
100             sub loop {
101 0     0 0   my $self = shift;
102 0           my %args = @_;
103 0           my ($poe, $rsvp, $from, $args) = (
104             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
105 0           my $kernel = $poe->kernel;
106              
107 0 0         $DEBUG and _DEBUG_log($args);
108              
109 0 0 0       my $limit = shift @{$args} if ($args->[0] and $args->[0] =~ /^\d+$/);
  0            
110              
111 0   0       my $func_full_name = $args->[0] || return;
112 0 0         $DEBUG and _DEBUG_log("func_full_name=>"=>$func_full_name);
113 0 0         $DEBUG and _DEBUG_log($args);
114              
115 0           my $destination;
116 0           ($destination, $args) = $self->_distinguish(poe=>$poe, args=>$args);
117 0           my $module = shift @{$args};
  0            
118 0           my $method = shift @{$args};
  0            
119 0 0         $DEBUG and _DEBUG_log("module=>"=>$module);
120              
121 0 0         $self->use(module=>$module) or return $@;
122              
123 0           my $module_delay = '\$'."${module}::delay";
124 0           $module_delay = eval $module_delay;
125              
126 0           my $event_name = join "_" => $module =~ /(\w+)/, $method, 'loop';
127 0 0         $DEBUG and _DEBUG_log($event_name);
128              
129 0 0         if ($func_full_name) {
130 0           $self->state_list->{$func_full_name} =
131             POEIKC::Daemon::State->new(
132             event_name =>$event_name,
133             next_mthod =>'',
134             limit =>$limit,
135             destination =>$destination,
136             module =>$module,
137             method =>$method,
138             module_delay =>$module_delay
139             );
140             $kernel->state( $event_name , sub {
141 0     0     my @args = @_[POE::Session::ARG0() ..$#_];
142 0 0         $DEBUG and _DEBUG_log(@args);
143 0 0 0       if ($limit and not $self->state_list->{$func_full_name}->{limit}) {
144 0           $self->stop(poe=>$poe, something=>$func_full_name, );
145 0           return;
146             }
147 0           my @re_args = $self->execute(
148             poe=>$poe, from=>$destination, module=>$module, method=>$method, args=>\@args
149             );
150              
151 0           my $delay = ${$self->state_list->{$func_full_name}->module_delay};
  0            
152 0 0         $DEBUG and _DEBUG_log($delay);
153 0 0         $delay ?
154             $kernel->delay($event_name => $delay, @re_args) :
155             $kernel->yield($event_name, @re_args);
156              
157 0 0         $self->state_list->{$func_full_name}->{limit}-- if ($limit);
158             }
159 0           );
160 0           $kernel->yield($event_name, @{$args});
  0            
161 0           return $event_name;
162             }else{
163 0           return;
164             }
165             }
166              
167              
168             sub relay #{}
169             {
170 0     0 0   my $self = shift;
171 0           my %args = @_;
172 0           my ($poe, $rsvp, $from, $args) = (
173             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
174 0           my $kernel = $poe->kernel;
175              
176 0 0         $DEBUG and _DEBUG_log($args);
177              
178 0   0       my $something = $args->[0] || return;
179              
180 0           my $destination;
181 0           ($destination, $args) = $self->_distinguish(poe=>$poe, args=>$args);
182 0           my $module = shift @{$args};
  0            
183 0           my $method = $args->[0];
184              
185 0 0         $self->use(module=>$module) or return $@;
186              
187 0           my $module_delay = '\$'."${module}::delay";
188 0           $module_delay = eval $module_delay;
189              
190 0           my $event_name = join "_" => $module =~ /(\w+)/, $method, 'relay';
191              
192 0 0         $DEBUG and _DEBUG_log($event_name, $something);
193              
194 0 0         if ($something) {
195 0           $self->state_list->{$something} =
196             POEIKC::Daemon::State->new(
197             event_name=>$event_name,
198             next_mthod=>'',
199             destination=>[$destination, $module, $method],
200             module_delay =>$module_delay
201             );
202             $kernel->state( $event_name , sub {
203 0     0     my @args = @_[POE::Session::ARG0() ..$#_];
204 0 0         $DEBUG and _DEBUG_log(\@args);
205 0           my $method = shift @args;
206 0 0         $DEBUG and _DEBUG_log( from=>$destination, module=>$module, method=>$method, args=>\@args);
207 0           my @re_args = $self->execute(poe=>$poe, from=>$destination, module=>$module, method=>$method, args=>\@args);
208 0 0         $DEBUG and _DEBUG_log(@re_args);
209 0 0 0       my $delay = shift @re_args if ($re_args[0] and not(ref $re_args[0]) and $re_args[0] =~ /^\d+$/);
      0        
210 0 0 0       my $next_mthod = $re_args[0] if ($re_args[0] and not(ref $re_args[0]) and $re_args[0] =~ /^\w+/);
      0        
211              
212 0 0         (not $next_mthod) ?
    0          
213             $self->stop(poe=>$poe, something=>$something,) :
214             $delay ?
215             $kernel->delay($event_name => $delay, @re_args ) :
216             $kernel->yield($event_name, @re_args ) ;
217             }
218 0           );
219 0           $kernel->yield($event_name => @{$args});
  0            
220 0           return $event_name;
221             }else{
222 0           return;
223             }
224             }
225              
226             sub chain #{}
227             {
228 0     0 0   my $self = shift;
229 0           my %args = @_;
230 0           my ($poe, $rsvp, $from, $args) = (
231             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
232 0           my $kernel = $poe->kernel;
233              
234 0 0         $DEBUG and _DEBUG_log($args);
235              
236 0   0       my $something = $args->[0] || return;
237              
238 0           my $destination;
239 0           ($destination, $args) = $self->_distinguish(poe=>$poe, args=>$args);
240 0           my $module = shift @{$args};
  0            
241 0           my $method = shift @{$args};
  0            
242 0           my @next_mthod = split /,/ => shift @{$args};
  0            
243 0           unshift @next_mthod , $method;
244              
245 0 0         $self->use(module=>$module) or return $@;
246              
247 0           my $module_delay = '\$'."${module}::delay";
248 0           $module_delay = eval $module_delay;
249              
250 0           my $event_name = join "_" => $module =~ /(\w+)/, $method, 'chain';
251              
252 0 0         $DEBUG and _DEBUG_log($event_name, $something);
253              
254 0 0         if ($something) {
255 0           $self->state_list->{$something} =
256             POEIKC::Daemon::State->new(
257             event_name=>$event_name,
258             next_mthod=>\@next_mthod,
259             pointer=>0,
260             destination=>[$destination, $module, $method],
261             module_delay =>$module_delay
262             );
263             $kernel->state( $event_name , sub {
264 0     0     my @args = @_[POE::Session::ARG0() ..$#_];
265 0 0         $DEBUG and _DEBUG_log(\@args);
266 0           my $pointer = $self->state_list->{$something}->{pointer};
267 0           my $method = $self->state_list->{$something}->{next_mthod}->[$pointer];
268 0           my @re_args = $self->execute(poe=>$poe, from=>$destination, module=>$module, method=>$method, args=>\@args);
269 0           $self->state_list->{$something}->{pointer}++;
270 0 0         ($pointer >= $#{$self->state_list->{$something}->{next_mthod}})
  0            
271             ?
272             $self->stop(poe=>$poe, something=>$something,) :
273             $kernel->yield($event_name, @re_args ) ;
274             }
275 0           );
276 0           $kernel->yield($event_name => @{$args});
  0            
277 0           return $event_name;
278             }else{
279 0           return;
280             }
281             }
282              
283              
284              
285             ### exec vvvvvvvvvvvvvvvvvvvvvvvvv
286              
287             sub execute {
288 0     0 0   my $self = shift;
289 0           my %args = @_;
290 0           my ($poe, $rsvp, $from, $args) = (
291             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
292 0           my ($module, $method) = ( $args{module}, $args{method} );
293 0 0         my $kernel = $poe->kernel if $poe;
294             #_DEBUG_log(wantarray);
295 0           for ($from) {
296 0 0         /^method/ and return eval {
297 0 0         $DEBUG and _DEBUG_log("$module->$method( @{$args} )");
  0            
298 0           $module->$method( @{$args} )
  0            
299             } ;
300 0 0         /^event/ and return eval {
301 0           local $! = undef;
302 0 0         $DEBUG and _DEBUG_log("call( $module => $method, @{$args} )");
  0            
303 0 0         $kernel->call( $module => $method, @{$args} )or return $!
  0            
304             } ;
305 0 0         /^function/ and return eval {
306 1     1   6360 no strict 'refs';
  1         3  
  1         1691  
307 0           my $code = "${module}::$method";
308 0 0         $DEBUG and _DEBUG_log($code);
309 0 0         $DEBUG and _DEBUG_log("$code(@{$args})");
  0            
310 0           $code = *{$code};
  0            
311 0 0         $DEBUG and _DEBUG_log("defined($code) ?=>"=>defined(&$code));
312 0           $code->( @{$args} );
  0            
313             };
314             }
315 0           return {poeikcd_error=>
316             'It is not discriminable. '.
317             q{"ModuleName::functionName" or "ClassName->methodName" or "AliasName eventName"}
318             }
319             }
320              
321             ### get vvvvvvvvvvvvvvvvvvvvvvvvv
322              
323 0     0 0   sub get_A_INC { return \@INC }
324 0     0 0   sub get_H_INC { return \%INC }
325 0     0 0   sub get_H_ENV { return \%ENV }
326 0     0 0   sub get_pid { return $$ }
327 0     0 0   sub get_VERSION { return $POEIKC::Daemon::VERSION }
328              
329             sub get_stay {
330 0     0 0   my $self = shift;
331 0           return $self->inc->{stay};
332             }
333              
334             sub get_load {
335 0     0 0   my $self = shift;
336 0           return $self->inc->{load};
337             }
338              
339             sub get_session_alias_list {
340 0 0   0 0   POE::API::Peek->use or return $@;
341 0           my $api = POE::API::Peek->new;
342 0           my %alias;
343 0           for ($api->session_list()){
344 0           my $id = $_->ID;
345 0           my @list = $api->session_alias_list($_);
346 0 0         $alias{$id} = (1 == @list) ? shift @list : \@list;
347             #$DEBUG and _DEBUG_log( @list );
348             }
349 0           return \%alias;
350             }
351              
352             sub get_session_id_list {
353 0 0   0 0   POE::API::Peek->use or return $@;
354 0           my $api = POE::API::Peek->new;
355 0           my @list = $api->session_list();
356 0 0         $DEBUG and _DEBUG_log( @list );
357 0           @list = map {$_->ID} @list;
  0            
358 0           return \@list;
359             }
360              
361             sub get_poe_api_peek {
362 0     0 0   my $self = shift;
363 0           my %args = @_;
364 0           my ($poe, $rsvp, $from, $args) = (
365             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
366 0 0         POE::API::Peek->use or return $@;
367 0   0       my $subname = shift @{$args{args}} || return;
368 0           my $api = POE::API::Peek->new;
369 0           my @list = $api->$subname(@{$args{args}});
  0            
370 0 0         $DEBUG and _DEBUG_log( @list );
371 0           return \@list;
372             }
373              
374             sub get_methods {
375 0     0 0   my $self = shift;
376 0           my %args = @_;
377 0           my ($poe, $rsvp, $from, $args) = (
378             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
379 0 0         my $module = shift @{$args{args}} or return;
  0            
380 0           return Class::Inspector->methods($module);
381             }
382              
383             sub get_Class_Inspector {
384 0     0 0   my $self = shift;
385 0           my %args = @_;
386 0           my ($poe, $rsvp, $from, $args) = (
387             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
388 0 0         my $module = shift @{$args{args}} or return;
  0            
389 0 0         return not(@{$args}) ? Class::Inspector->methods('Class::Inspector') : do {
  0            
390 0           my $method = shift @{$args};
  0            
391 0           Class::Inspector->$method($module);
392             };
393             }
394              
395             sub get_object_something {
396 0     0 0   my $self = shift;
397 0           my %args = @_;
398 0           my $poe = $args{poe};
399 0           my ($something) = @{$args{args}};
  0            
400 0           return $poe->object->{$something}; # ikc_self_port alias;
401             }
402              
403             ### INC vvvvvvvvvvvvvvvvvvvvvvvvv
404              
405             sub unshift_INC {
406 0     0 0   my $self = shift;
407 0           my %args = @_;
408 0           my ($poe, $rsvp, $from, $args) = (
409             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
410 0           for( @{$args{args}} ){
  0            
411 0 0         unshift @INC, map {m'\$' and do{ $_= eval qq{"$_"}} ;s/~/$ENV{HOME}/;$_} split /:/ => $_;
  0            
  0            
  0            
  0            
412             }
413 0           my %inc;
414 0           @INC = grep {
415 0 0         $inc{$_} ? () : do{$inc{$_}++;$_};
  0            
  0            
416             } @INC;
417 0           return \@INC;
418             }
419              
420             sub reset_INC {
421 0     0 0   my $self = shift;
422 0           my %args = @_;
423 0           my ($poe, $rsvp, $from, $args) = (
424             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
425 0           my $path = shift @{$args{args}};
  0            
426 0           @INC = @POEIKC::Daemon::inc;
427 0           return \@INC;
428             }
429              
430             sub delete_INC {
431 0     0 0   my $self = shift;
432 0           my %args = @_;
433 0           my ($poe, $rsvp, $from, $args) = (
434             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
435 0           my $path = shift @{$args{args}};
  0            
436 0           @INC = grep {$_ ne $path} @INC;
  0            
437 0           return \@INC;
438             }
439              
440             sub use {
441 0     0 0   my $self = shift;
442 0           my %args = @_;
443 0           my ($poe, $rsvp, $from, $module, $args) = (
444             $args{poe}, $args{rsvp}, $args{from}, $args{module}, $args{args} );
445 0 0 0       $module ||= shift @{$args{args}} or return;
  0            
446 0 0         return Class::Inspector->loaded( $module ) ? 1 : do{
    0          
447 0 0         $module->use() or return ;
448 0           $self->inc->{load}->{ $module } = [$INC{Class::Inspector->filename($module)},scalar localtime] ;
449 0           1;
450             }? 1 : ();
451             }
452              
453              
454              
455             sub stay {
456 0     0 0   my $self = shift;
457 0           my %args = @_;
458 0           my ($poe, $rsvp, $from, $module, $args) = (
459             $args{poe}, $args{rsvp}, $args{from}, $args{module}, $args{args} );
460 0 0 0       $module ||= shift @{$args{args}} or return;
  0            
461 0   0       $self->inc->{stay}->{$module} ||= time;
462 0           return $self->inc->{stay};
463             }
464              
465              
466             sub reload {
467 0     0 0   my $self = shift;
468 0           my %args = @_;
469 0           my ($poe, $rsvp, $from, $args) = (
470             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
471 0 0         my $module = shift @{$args{args}} or return;
  0            
472              
473 0           my @deletelist;
474              
475 0 0 0       if (not $self->inc->{stay}->{$module} and $module ne __PACKAGE__) {
476 1     1   6 no warnings;
  1         2  
  1         99  
477 0           for ( sort keys %INC ){
478 0 0         next if $self->inc->{org_inc}->{$_} ;
479 0 0         next if $self->inc->{stay}->{$_};
480 0           push @deletelist, delete $INC{$_};
481             }
482 1     1   6 {no strict 'refs';%{"${module}::"}=();}
  1         1  
  1         1426  
  0            
  0            
  0            
483 0           delete $self->inc->{load}->{$module};
484             }
485              
486 0 0         if( @{$args} >= 1) {
  0            
487 0           unshift @{$args}, $module;
  0            
488 0 0         $DEBUG and _DEBUG_log($rsvp, $args);
489 0 0         $poe->kernel->call($poe->session => execute_respond => $from, $args, $rsvp )
490             or return $!;
491 0           $rsvp->{responded} = (caller(0))[3];
492             }else{
493 0           return \@deletelist;
494             }
495             }
496              
497             ### eval vvvvvvvvvvvvvvvvvvvvvvvvv
498              
499             sub eval {
500 0     0 0   my $self = shift;
501 0           my %args = @_;
502 0           my $args = $args{args};
503              
504 0 0         my $expr = (ref $args eq 'ARRAY') ? shift @{$args} : $args;
  0            
505              
506 0 0         $DEBUG and _DEBUG_log($expr);
507              
508 0   0       return eval $expr || $@;
509             }
510              
511              
512             ### IKC vvvvvvvvvvvvvvvvvvvvvvvvv
513              
514             sub publish_IKC {
515 0     0 0   my $self = shift;
516 0           my %args = @_;
517 0           my ($poe, $rsvp, $from, $args) = (
518             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
519 0           my ($alias, $event_ary) = ($args{alias}, $args{event});
520 0 0 0       if (not($alias) and not($event_ary) and ($args)){
      0        
521 0           $alias = shift @{$args};
  0            
522 0           my $flag_packagename_or_eventlist = shift @{$args};
  0            
523 0 0         $event_ary = $flag_packagename_or_eventlist =~ /^_list$/i ? $args : do{
524 0           Class::Inspector->methods($flag_packagename_or_eventlist);
525             };
526             }
527 0 0         $DEBUG and _DEBUG_log( $alias, $event_ary);
528 0 0 0       return if (not($alias) or not($event_ary));
529 0   0       return $poe->kernel->call(IKC =>publish => $alias, $event_ary) || $!;
530             }
531              
532              
533              
534             ###
535              
536             sub _distinguish {
537 0     0     my $self = shift;
538 0           my %args = @_;
539 0           my ($poe, $rsvp, $from, $args) = (
540             $args{poe}, $args{rsvp}, $args{from}, $args{args} );
541 0           my $kernel = $poe->kernel;
542              
543 0 0         $DEBUG and _DEBUG_log($args);
544              
545 0           my $something ;
546 0           my ($module, $method);
547             {
548 0 0         $kernel->alias_list($args->[0]) and do {
  0            
549             # event_respond
550 0           $module = shift @{$args};
  0            
551 0           $method = shift @{$args};
  0            
552 0 0         $module or last; $method or last;
  0 0          
553             #keys $self->pidu->inc->{load}
554 0           unshift @{$args}, $module, $method;
  0            
555 0           return ('event', $args);
556             };
557 0 0         $args->[0] =~ /->/ and do {
558             # method_respond
559 0           $module = $`;
560 0           $method = $';
561 0 0         $module or last; $method or last;
  0 0          
562 0           shift @{$args};
  0            
563 0           unshift @{$args}, $module, $method;
  0            
564 0           return ('method', $args);
565             };
566 0 0         $args->[0] =~ /::(\w+)$/ and do {
567             # function_respond
568 0           $module = $`;
569 0           $method = $1;
570 0 0         $module or last; $method or last;
  0 0          
571 0           shift @{$args};
  0            
572 0           unshift @{$args}, $module, $method;
  0            
573 0           return ('function', $args);
574             };
575             }
576 0 0         $DEBUG and _DEBUG_log();
577             return
578 0           }
579              
580             ### DEBUG vvvvvvvvvvvvvvvvvvvvvvvvv
581              
582             sub _DEBUG_log {
583 0 0   0     $DEBUG or return;
584 0 0         Date::Calc->use or return(warn($@));
585             #YAML->use or return;
586 0           my ($pack, $file, $line, $subroutine) = caller(0);
587 0           my $levels_up = 0 ;
588 0           ($pack, $file, $line, ) = caller($levels_up);
589 0           $levels_up++;
590 0           (undef, undef, undef, $subroutine, ) = caller($levels_up);
591             {
592 0           (undef, undef, undef, $subroutine, ) = caller($levels_up);
  0            
593 0 0 0       if(defined $subroutine and $subroutine eq "(eval)") {
594 0           $levels_up++;
595 0           redo;
596             }
597 0 0         $subroutine = "main::" unless $subroutine;
598             }
599 0           my $log_header = sprintf "[DEBUG %04d/%02d/%02d %02d:%02d:%02d %s %d %s %d %s] - ",
600             Date::Calc::Today_and_Now() , $ENV{HOSTNAME}, $$, $file, $line, $subroutine;
601 0           my @data = @_;
602 0 0         print(
    0          
603             $log_header, (join "\t" => map {
604 0           ref($_) ? Data::Dumper::Dumper($_) :
605             defined $_ ? $_ : "`'" ;
606             } @data ),"\n"
607             );
608             }
609              
610             sub _log_header {
611 0 0   0     Date::Calc->use or return;
612 0           my ($pack, $file, $line, $subroutine) = caller(0);
613 0           my $levels_up = 0 ;
614 0           ($pack, $file, $line, ) = caller($levels_up);
615 0           $levels_up++;
616 0           (undef, undef, undef, $subroutine, ) = caller($levels_up);
617             {
618 0           (undef, undef, undef, $subroutine, ) = caller($levels_up);
  0            
619 0 0 0       if(defined $subroutine and $subroutine eq "(eval)") {
620 0           $levels_up++;
621 0           redo;
622             }
623 0 0         $subroutine = "main::" unless $subroutine;
624             }
625 0           return sprintf "[DEBUG %04d/%02d/%02d %02d:%02d:%02d %s %d %s %d %s] - ",
626             Date::Calc::Today_and_Now() , $ENV{HOSTNAME}, $$, $file, $line, $subroutine;
627             }
628              
629             1;
630              
631             __END__