Apache-HeavyCGI
view release on metacpan or search on metacpan
lib/Apache/HeavyCGI/ExePlan.pm view on Meta::CPAN
package Apache::HeavyCGI::ExePlan;
use Apache::HeavyCGI; # want only the instance_of method
use strict;
# use fields qw(PLAN DEBUG FUNCTIONAL WATCHVARIABLE);
use vars '$VERSION';
$VERSION = sprintf "%d.%03d", q$Revision: 1.10 $ =~ /(\d+)\.(\d+)/;
# no singleton, every Application can have its own execution plan even
# every object can have it's own, although, it probably doesn't pay
sub new {
my($me,%arg) = @_;
my $methods = $arg{METHODS} || [qw(header parameter)];
my $classes = $arg{CLASSES} || [];
my $functional = $arg{WALKTYPE} eq "f";
my $watchvariable = $arg{WATCHVARIABLE};
my $debug = $arg{DEBUG} || 0; #### undocumented
my @plan;
for my $method (@$methods) {
for my $class (@$classes) {
my($obj,$subr);
eval { $obj = $class->instance; };
if ($@) {
$obj = Apache::HeavyCGI->instance_of($class);
}
next unless $subr = $obj->can($method);
if ($functional) {
push @plan, $subr, $obj;
} else {
push @plan, $obj, $method;
}
}
}
no strict "refs";
my $self = bless {}, $me;
$self->{PLAN} = [ @plan ];
$self->{DEBUG} = $debug;
$self->{FUNCTIONAL} = $functional;
$self->{WATCHVARIABLE} = $watchvariable;
$self;
}
sub walk {
my Apache::HeavyCGI::ExePlan $self = shift;
my Apache::HeavyCGI $application = shift;
if ($self->{WATCHVARIABLE}) {
require Data::Dumper;
}
for (my $i=0;;$i+=2) {
warn sprintf(
"entering method[%s] walktype[%s]",
$self->{PLAN}[$i]."::".$self->{PLAN}[$i+1],
$self->{FUNCTIONAL} ? "f" : "m",
) if $self->{DEBUG} && $self->{DEBUG} & 1;
my $before = $self->{WATCHVARIABLE} ?
Data::Dumper::Dumper($application->{$self->{WATCHVARIABLE}}) :
"";
if ($self->{FUNCTIONAL}) {
my $subr = $self->{PLAN}[$i] or last;
my $obj = $self->{PLAN}[$i+1];
$subr->($obj,$application);
} else {
my $obj = $self->{PLAN}[$i] or last;
my $method = $self->{PLAN}[$i+1];
$obj->$method($application);
}
warn sprintf "exiting" if $self->{DEBUG} && $self->{DEBUG} & 2;
my $after = $self->{WATCHVARIABLE} ?
Data::Dumper::Dumper($application->{$self->{WATCHVARIABLE}}) : "";
unless ($before eq $after) {
warn sprintf(
"variable %s changed value from[%s]to[%s] in method[%s]",
$self->{WATCHVARIABLE},
$before,
$after,
$self->{PLAN}[$i]."::".$self->{PLAN}[$i+1],
);
}
}
}
1;
__END__
=head1 NAME
Apache::HeavyCGI::ExePlan - Creates an execution plan for Apache::HeavyCGI
=head1 SYNOPSIS
use Apache::HeavyCGI::ExePlan;
my $plan = Apache::HeavyCGI::ExePlan->new(
METHODS => ["header", "parameter"],
CLASSES => ["my_application::foo", "my_application::bar", ... ],
DEBUG => 1,
WALKTYPE => "m",
WATCHVARIABLE => "SOME VARIABLE",
$plan->walk;
=head1 DESCRIPTION
When an execution plan object is instantiated, it immediately visits
all specified classes, collects the singleton objects for these
classes, and checks if the classes define the specified methods. It
creates an array of objects and methods or an array of code
references.
The walk method walks through the execution plan in the stored order
and sends each singleton object the appropriate method and passes the
application object as the first argument.
Normally, every application has its own execution plan. If the
execution plan is calculated at load time of the application class,
all objects of this class can share a common execution plan, thus
speeding up the requests. Consequently it is recommended to have an
initialization in all applications that instantiates an execution plan
and passes it to all application objects in the constructor.
=head1 ARGUMENTS TO THE CONSTRUCTOR
=over
=item METHODS
An anonymous array consisting of method names that shall be called
when walk() is called. Defaults to
( run in 2.663 seconds using v1.01-cache-2.11-cpan-5837b0d9d2c )