home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / ExePlan.pm < prev    next >
Encoding:
Perl POD Document  |  2001-07-13  |  5.4 KB  |  170 lines

  1. package Apache::HeavyCGI::ExePlan;
  2. use Apache::HeavyCGI; # want only the instance_of method
  3. use strict;
  4. use fields qw(PLAN DEBUG FUNCTIONAL WATCHVARIABLE);
  5.  
  6. use vars '%FIELDS', '$VERSION';
  7. $VERSION = sprintf "%d.%03d", q$Revision: 1.10 $ =~ /(\d+)\.(\d+)/;
  8.  
  9. # no singleton, every Application can have its own execution plan even
  10. # every object can have it's own, although, it probably doesn't pay
  11.  
  12. sub new {
  13.   my($me,%arg) = @_;
  14.   my $methods = $arg{METHODS} || [qw(header parameter)];
  15.   my $classes = $arg{CLASSES} || [];
  16.   my $functional = $arg{WALKTYPE} eq "f";
  17.   my $watchvariable = $arg{WATCHVARIABLE};
  18.   my $debug   = $arg{DEBUG} || 0; #### undocumented
  19.   my @plan;
  20.   for my $method (@$methods) {
  21.     for my $class (@$classes) {
  22.       my($obj,$subr);
  23.       eval { $obj = $class->instance; };
  24.       if ($@) {
  25.     $obj = Apache::HeavyCGI->instance_of($class);
  26.       }
  27.       next unless $subr = $obj->can($method);
  28.       if ($functional) {
  29.     push @plan, $subr, $obj;
  30.       } else {
  31.     push @plan, $obj, $method;
  32.       }
  33.     }
  34.   }
  35.   no strict "refs";
  36.   my $self = bless [\%{"$me\::FIELDS"}], $me;
  37.   $self->{PLAN} = [ @plan ];
  38.   $self->{DEBUG} = $debug;
  39.   $self->{FUNCTIONAL} = $functional;
  40.   $self->{WATCHVARIABLE} = $watchvariable;
  41.   $self;
  42. }
  43.  
  44. sub walk {
  45.   my Apache::HeavyCGI::ExePlan $self = shift;
  46.   my Apache::HeavyCGI $application = shift;
  47.   if ($self->{WATCHVARIABLE}) {
  48.     require Data::Dumper;
  49.   }
  50.   for (my $i=0;;$i+=2) {
  51.     warn sprintf(
  52.                  "entering method[%s] walktype[%s]",
  53.                  $self->{PLAN}[$i]."::".$self->{PLAN}[$i+1],
  54.                  $self->{FUNCTIONAL} ? "f" : "m",
  55.                 ) if $self->{DEBUG} && $self->{DEBUG} & 1;
  56.     my $before = $self->{WATCHVARIABLE} ?
  57.         Data::Dumper::Dumper($application->{$self->{WATCHVARIABLE}}) :
  58.               "";
  59.     if ($self->{FUNCTIONAL}) {
  60.       my $subr = $self->{PLAN}[$i] or last;
  61.       my $obj = $self->{PLAN}[$i+1];
  62.       $subr->($obj,$application);
  63.     } else {
  64.       my $obj = $self->{PLAN}[$i] or last;
  65.       my $method = $self->{PLAN}[$i+1];
  66.       $obj->$method($application);
  67.     }
  68.     warn sprintf "exiting" if $self->{DEBUG} && $self->{DEBUG} & 2;
  69.     my $after = $self->{WATCHVARIABLE} ?
  70.         Data::Dumper::Dumper($application->{$self->{WATCHVARIABLE}}) : "";
  71.     unless ($before eq $after) {
  72.       warn sprintf(
  73.                    "variable %s changed value from[%s]to[%s] in method[%s]",
  74.                    $self->{WATCHVARIABLE},
  75.                    $before,
  76.                    $after,
  77.                    $self->{PLAN}[$i]."::".$self->{PLAN}[$i+1],
  78.                   );
  79.     }
  80.   }
  81. }
  82.  
  83. 1;
  84.  
  85. __END__
  86.  
  87.  
  88. =head1 NAME
  89.  
  90. Apache::HeavyCGI::ExePlan - Creates an execution plan for Apache::HeavyCGI
  91.  
  92. =head1 SYNOPSIS
  93.  
  94.  use Apache::HeavyCGI::ExePlan;
  95.  my $plan = Apache::HeavyCGI::ExePlan->new(
  96.     METHODS => ["header", "parameter"],
  97.     CLASSES => ["my_application::foo", "my_application::bar", ... ],
  98.     DEBUG    => 1,
  99.     WALKTYPE => "m",
  100.     WATCHVARIABLE => "SOME VARIABLE",
  101.  
  102.  $plan->walk;
  103.  
  104. =head1 DESCRIPTION
  105.  
  106. When an execution plan object is instantiated, it immediately visits
  107. all specified classes, collects the singleton objects for these
  108. classes, and checks if the classes define the specified methods. It
  109. creates an array of objects and methods or an array of code
  110. references.
  111.  
  112. The walk method walks through the execution plan in the stored order
  113. and sends each singleton object the appropriate method and passes the
  114. application object as the first argument.
  115.  
  116. Normally, every application has its own execution plan. If the
  117. execution plan is calculated at load time of the application class,
  118. all objects of this class can share a common execution plan, thus
  119. speeding up the requests. Consequently it is recommended to have an
  120. initialization in all applications that instantiates an execution plan
  121. and passes it to all application objects in the constructor.
  122.  
  123. =head1 ARGUMENTS TO THE CONSTRUCTOR
  124.  
  125. =over
  126.  
  127. =item METHODS
  128.  
  129. An anonymous array consisting of method names that shall be called
  130. when walk() is called. Defaults to
  131.  
  132.     [qw(header parameter)]
  133.  
  134. =item CLASSES
  135.  
  136. An anonymous array of class names (a.k.a. widgets) that shall be
  137. visited when walk() is called. Has no default.
  138.  
  139. =item DEBUG
  140.  
  141. Currently only 0 and 1, 2 or 3 are allowed. If 1, each class/method
  142. pair triggers a warning on entering their execution. If 2, the warning
  143. is triggered at exit of the subroutine. If 3, both entry and exit
  144. trigger a warning.
  145.  
  146. =item WATCHVARIABLE
  147.  
  148. Name of a member variable. Defaults to C<undef>. By setting
  149. WATCHVARIABLE you can watch a member variable of the Apache::HeavyCGI
  150. object on entering/exiting each call to each class/method pair. Only
  151. changes of the variable trigger a warning.
  152.  
  153. =item WALKTYPE
  154.  
  155. A single letter, either C<m> (default) or C<f>. If set to C<m>, all
  156. method calls issued by the call to walk() are execute as method calls.
  157. If set to C<f>, all method calls are replaced by their equivalent
  158. subroutine calls, bypassing perl's method dispatch algorithm. The
  159. latter is recommended on the production server, the former is
  160. recommended in the development environment. C<m> allows you to use the
  161. Apache::StatINC module with the effect it usually has. Using
  162. Apache::StatINC with WALKTYPE=f has B<no effect>, as all subroutines
  163. are preserved when Apache::StatINC reloads a file, so the execution
  164. plan will not note the change.
  165.  
  166. =back
  167.  
  168. =cut
  169.  
  170.