Agent-TCLI
view release on metacpan or search on metacpan
lib/Agent/TCLI/Base.pm view on Meta::CPAN
=cut
use warnings;
use strict;
use Carp;
our $VERSION = '0.030.'.sprintf "%04d", (qw($Id: Base.pm 59 2007-04-30 11:24:24Z hacker $))[2];
use Object::InsideOut;
use Data::Dump qw(pp);
=head2 ATTRIBUTES
The following attributes are accessible through standard accessor/mutator
methods and may be set as a parameter to new unless otherwise noted.
=over
=cut
# Standard class utils
# I need to redo err handling as its not useful as is.
=item err
Error message if something went wrong with a method call. Cannot be set or
passed in with new. Not actually used, as erroring needs to be revisited.
=cut
my @err :Field
:Get('err');
=item verbose
Turns on/off internal state messages and warnings. Higher values produce more
verbosity.
=cut
# TODO change verbose to verbosity
my @verbose :Field
:Arg('Name' => 'verbose', 'Default' => 0 )
:Acc('verbose');
=item do_verbose
A routine to output the results of a verbose call.
This allows it to be changed within an object.
B<do_verbose> will only accept code type values.
=cut
my @do_verbose :Field
:Arg('Name' => 'do_verbose', 'Default' => sub { print (@_) } )
:Acc('do_verbose')
:Type('CODE');
sub _set_err {
my ($self, $args) = @_;
$self->set(\@err, $args);
$self->Verbose("Err called");
return undef;
}
=back
=head2 METHODS
=over
=item Verbose (<message>, [ <level>, <dump_var> ] )
This method is use to output all logging and debugging commands. It will use
the sub in do_verbose to output the message if the level is less than or
equal to the current value of $self->verbose. If level is not suppiled,
it defaults to one.
If a dump_var is included, its value will be output using the Data::Dump::pp
function. This can pe useful for checking the inside of array, hashes
and objects. If the object is an OIO object, use the objects own $obj->dump(1)
method in the message.
=cut
sub Verbose {
my ($self, $message, $level, $var) = @_;
$level = 1 unless defined($level);
# Support Verbose in init before default is set:
# That means it has to be set to zero. :)
my $verbose = defined($self->verbose) ? $self->verbose : 0;
# Dereference, if necessary
$verbose = ref($verbose) ? $$verbose : $verbose;
my $do_verbose = defined($self->do_verbose) ? $self->do_verbose :
sub { print (@_) };
# I suppose I could take out the defaults now, but that is better
# so that the effective values can be read.
return unless ( $verbose >= $level );
my $class = $self->dump()->[0];
my $txt = $level.":".$class.":".$message."\n";
if (defined($var))
{
my $tmp = $var;
if ( ref($tmp) =~ /TCLI/ ) # Its one of mine and OIO
{
$txt .= $tmp->dump(1)."\n";
}
else
{
$txt .= pp($tmp)."\n";
}
}
# objects may override output format by changing do_verbose
&{$do_verbose}($txt);
return ($txt);
}
=item _automethod
Several TCLI classes take advantage of automethods to enable extending classes
to store information. There are also Numeric, Array and Hash automethods
lib/Agent/TCLI/Base.pm view on Meta::CPAN
# ARRAY Methods
($action, $field_name) = $method =~ /^(print|depth|push|pop|shift|unshift)_(.*)$/;
if ($field_name)
{
if (defined( $meth->{$field_name} ) &&
$meth->{$field_name}{'type'} =~ /list|array/ )
{
# Has combined accessor
$accessor = $mutator = $field_name;
$self->Verbose( "_automethod combined action($action) field_name($field_name) \n",3);
}
elsif ( defined( $meth->{"set_$field_name"} ) &&
$meth->{"set_$field_name"}{'type'} =~ /list|array/ )
{
# Has standard accessor
$accessor = "get_".$field_name;
$mutator = "set_".$field_name;
$self->Verbose("_automethod standard action($action) mutator($mutator) accessor($accessor) \n",3);
}
elsif ($field_name =~ /array/ && !defined($meth->{"set_$field_name"} ) )
{
$accessor = "get_".$field_name;
$mutator = "set_".$field_name;
$self->Verbose("_automethod new standard action($action) mutator($mutator) accessor($accessor) \n",3);
# Make standard mutator/accessor
$self->$mutator( [ ] );
}
else
{
$self->Verbose("_automethod meth",0,$meth);
return; # Not an array or unrecognized.
}
my $handler;
$self->Verbose("_automethod self",4,$self->$accessor );
$self->Verbose("_automethod field_name($field_name)",5,$meth);
if ( $action eq 'push' )
{
$handler = sub {
my $self = shift;
if ( defined($self->$accessor) )
{
return ( push( @{ $self->$accessor }, @_ ) )
}
else
{
$self->$mutator([ @_ ]);
return( scalar ( @{ $self->$accessor } ));
}
};
}
elsif ( $action eq 'pop' )
{
$handler = sub {
my $self = shift;
return ( pop( @{ $self->$accessor } ) )
if defined($self->$accessor);
return undef;
};
}
elsif ( $action eq 'shift' )
{
$handler = sub {
my $self = shift;
return ( shift (@{ $self->$accessor } ) )
if defined($self->$accessor);
return undef;
};
}
elsif ( $action eq 'unshift' )
{
$handler = sub {
my $self = shift;
if ( defined($self->$accessor) )
{
return ( unshift( @{ $self->$accessor }, @_ ) );
}
else
{
$self->$mutator([ @_ ]);
return( scalar ( @{ $self->$accessor } ));
}
};
}
elsif ( $action eq 'depth' )
{
$handler = sub {
my $self = shift;
return ( scalar( @{ $self->$accessor } ) )
if defined($self->$accessor);
return 0;
};
}
elsif ( $action eq 'print' )
{
$handler = sub {
my $self = shift;
return ( join(' ', @{ $self->$accessor } ) )
if defined($self->$accessor);
return '';
};
}
else
{
print "Whoops bad action($action) field_name($field_name) \n";
return;
}
### OPTIONAL ###
# Install the handler so it gets called directly next time
no strict 'refs';
*{$class.'::'.$method} = $handler;
################
return ($handler);
}
# HASH Methods
($action, $field_name) = $method =~ /^(sort)_(.*)$/;
if ($field_name)
{
if ($meth->{"$field_name"}{'type'} &&
$meth->{"$field_name"}{'type'} =~ /hash/ )
{
# Has combined accessor
}
elsif ($meth->{"$field_name"}{'type'} &&
$meth->{"set_$field_name"}{'type'} =~ /hash/ )
( run in 2.149 seconds using v1.01-cache-2.11-cpan-d80b1682f3f )