Well it might not be a function per say. It might be a statement or a series of functions or a method which needs it's state bound in the closure. Here's a simple example server monitor script. Note the module isn't done. I banged it out in a few hours and a few accessors and such are missing.
#!/usr/bin/perl -w package Function::Stats; ############################################################ # Copyright 2002 Lee Pumphret. All rights reserved. # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. ############################################################ use strict; use Time::HiRes qw(usleep time); use overload ( '""' => sub { my $self = shift; $self->{label} ? $self->{label} : "N +oName:$self"}, fallback => 1, ); sub new { my($class,@initializer) = @_; my $self = {}; bless $self,ref $class || $class; $self->_init(@initializer); return $self; } sub _init { my $self =shift; my %args = ( lastest=>15, # the number of iteration results to hang +onto. label => undef, sprint => '%0.4f', @_ ); die "$args{coderef} is not a CODEREF! ". ref $args{coderef} unles +s ref $args{coderef} eq 'CODE'; $args{boolean} = defined $args{boolean} ? $args{boolean} : undef; die "$args{boolean} is not a CODEREF!" unless !defined($args{boole +an}) || ref $args{boolean} eq 'CODE'; die "Can't have an array with no elements!. numlast bad" unless $a +rgs{lastest} >= 1; @{$self}{ qw( numlast coderef boolean label sprint) } = @args{ qw( + latest coderef boolean label sprint) }; $self->{latest} = [ ]; # latest result stored here. $self->{start_time} = time(); $self->{num_iterations} = 0; $self->{total_exectime} = 0; $self->{true} = 0; } ################################################### sub label { my $self = shift; return $self->{label}; } ################################################### sub runtime() { my $self = shift; my $now = time(); return $now - $self->{start_time}; } ################################################### sub iterations() { my $self = shift; return $self->{num_iterations}; } ################################################### sub latest() { my $self = shift; return @{ $self->{latest} }; } ################################################### sub failed() { my $self = shift; return $self->{num_iterations} - $self->{true} ; } ################################################### sub current_avg_failed() { my $self = shift; my $true = 0; my $numlast = $#{ $self->{latest} } + 1; return sprintf("$self->{sprint}","0.00") unless $numlast; foreach my $r( @{ $self->{latest} } ){ $true++ if defined $self->{boolean} ? $self->{boolean}->($r->[ +0]) : $r->[0]; } return sprintf("$self->{sprint}", ($numlast - $true) / $numlast + ); } ################################################### sub average_failed() { my $self = shift; return sprintf("$self->{sprint}", ($self->{num_iterations} - $self->{true}) / $self->{ +num_iterations} ); } ################################################### sub succeded() { my $self = shift; return $self->{true} ; } ################################################### sub average_succeded() { my $self = shift; return sprintf("$self->{sprint}", $self->{true} < $self->{num_iterations} ? $self->{true} / $self->{num_iterations} : 1 ); } ################################################### sub current_avg_succeded() { my $self = shift; my $true = 0; my $numlast = $#{ $self->{latest} } + 1; return sprintf("$self->{sprint}","0.00") unless $numlast; foreach my $r( @{ $self->{latest} } ){ $true++ if defined $self->{boolean} ? $self->{boolean}->($r->[ +0]) : $r->[0]; } return sprintf("$self->{sprint}", $true < $numlast ? $true / $ +numlast : 1 ); } ################################################### sub average_runtime { my $self = shift; return $self->{total_exectime} && $self->{num_iterations} ? $self- +>{total_exectime} / $self->{num_iterations} : 0 ; } ################################################### sub current_avg_runtime { my $self = shift; my $t = 0; foreach my $r( @{ $self->{latest} } ){ $t+= $r->[1]; } return $t / @{ $self->{latest} }; } ################################################### sub execute(){ my $self = shift; $self->{num_iterations}++; my $start = time(); my $res = $self->{coderef}->(); my $end = time(); my $diff = $end - $start; $self->{total_exectime}+= $end - $start; unshift @{ $self->{latest} }, [$res,$diff] ; $#{ $self->{latest} } = $self->{numlast} - 1 if $#{ $self->{lates +t} } >= $self->{numlast} + 1 ; $res = $self->{boolean}->($res) if defined $self->{boolean}; $self->{true}++ if $res; return $res; } ################################################### sub dumpstats { my $self = shift; my $padding = shift || ''; my $d ; my @d = ( $self->label, "Succeded: ".$self->succeded, "Failed: ".$self->failed, "Iterations: ".$self->iterations, "-" x 30, "Current Runtime Avg%: ".$self->current_avg_runtime." +seconds", "Current Success Avg%: ".$self->current_avg_succeded, "Current Failure Avg%: ".$self->current_avg_failed, "-" x 30, "Overall Runtime Avg%: ".$self->average_runtime." seco +nds", "Overall Success Avg%: ".$self->average_succeded, "Overall Failure Avg%: ".$self->average_failed, ); $d.=$padding.$_."\n" foreach (@d); $d; } ################################################### # main begins here... # ################################################### package main; use Net::Ping; use Filesys::DiskFree; use vars qw($STATUSMSG); my @hosts = qw (255.255.255.x 255.255.255.x 255.255.255.x 255.255.255. +x); sub pinger { my ($host,$timeout) = @_; $timeout = 5 unless $timeout; my $p = Net::Ping->new("icmp"); my $res = $p->ping($host,$timeout); $p->close(); return $res; } ################################# # Set up disk space monitoring. # ################################# my $dhandle = new Filesys::DiskFree; $dhandle->df(); my @disks = $dhandle->disks(); foreach my $disk( @disks){ $disk = Function::Stats->new( label => $disk , latest => 20, coderef => sub { $dhandle->avail($disk +) }, ); } ################################# # IPs to monitor. # ################################# foreach my $host (@hosts) { $host = Function::Stats->new( label => $host , latest => 10, coderef => sub { pinger($host,3) }, boolean => sub { my $r = shift; $STATUSMSG = $r ? "$ +host is up" : "$host is down!"; $r; } ); } ################################# # CTRL-C handler # ################################# my $signal = 0; local $SIG{INT} = sub { $signal++ }; ################################# # main loop # ################################# while (!$signal){ ################################ # Check disks # ################################ $dhandle->df; print "-" x 30 ,"\n" ; foreach my $disk (@disks){ my $space = $disk->execute(); print "filesystem:$disk has ",int($space /1024),"k available\n +"; if ($space < 1024 * 1024 * 20){ warn "\a$disk is low on $space!\n"; # Should email someone eh? } } ################################ # ping check IPs # ################################ foreach my $host (@hosts){ print "-" x 30 ,"\n" ; print "Host: $host\tInterval:",$host->iterations,"\n"; my $res = $host->execute; print $STATUSMSG,"\n"; if ($host->current_avg_failed > 0.25){ warn "\tConnection lacking for $host... ",$host->current_a +vg_failed,"% failure\n"; warn $host->dumpstats("\t"); } sleep(5); } } END{ print "#" x 30,"\nEnding....\n"; print "-" x 30,"\nSummary\n"; foreach my $disk (@disks){ print $disk->dumpstats; } print "-" x 30,"\n"; foreach my $host (@hosts){ print $host->dumpstats; } }


-Lee

"To be civilized is to deny one's nature."

In reply to Re: Re^3: OO lifetime function stats mod, is this useful? by shotgunefx
in thread OO lifetime function stats mod, is this useful? by shotgunefx

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.