You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Michael <mi...@bizsystems.com> on 2000/11/03 03:27:47 UTC

how to do this??

I have a handler which is called by Apache. The handler loads a 
module which has all the real subroutines within it that are 
executed. Ordinarily, a simple @EXPORT or @EXPORT_OK would provide 
the subroutines to the handler, but when Apache does the handoff, the 
PACKAGE name from the handler does not follow into the module 
subroutine, rather it is identified as Apache::Blah

i.e.

#handler
package MyHandler;

use Module qw(sub1 sub2);
use Apache;
use vars qw(@ISA)
@ISA = qw (Module Apache);

calling sub1 from apache
using THIS handler named "MyHandler" results in Module::sub1 
identifing the "caller" as Apache.

what is desired can be accomplished by

package MyHandler;
use Module
use Apache;
use vars qw(@ISA)
@ISA = qw (Module Apache);

sub sub1 {
  return Module::sub1{@};
}

now Module correctly identifies the caller as "MyHandler"

there are many routines in "Module", there ought to be a better way 
to do this. Any ideas would be appreciated.

One thought I had was to use a series of pointers
\*sub1 = *routine;
etc...

where & routine would identify the subroutine called. However, I 
don't know how to id the subr call.

Michael
Michael@Insulin-Pumpers.org

Re: how to do this??

Posted by Michael <mi...@bizsystems.com>.
> On Thu, 2 Nov 2000, Michael wrote:
> > #handler
> > package MyHandler;
> > 
> > use Module qw(sub1 sub2);
> > use Apache;
> > use vars qw(@ISA)
> > @ISA = qw (Module Apache);
> > 
> > calling sub1 from apache
> > using THIS handler named "MyHandler" results in Module::sub1 
> > identifing the "caller" as Apache.
> 
> Okay, I'll bite... Why do you want to change the caller?  I mean,
> Apache really is the caller if this is being invoked directly in
> response to a request.

You had to ask heh... heh...  code re-use of course.

I want to be able to use a custom set of variables (multiple 
personalities). i.e. create a module to do a common job. Apache 
directs the return to a handler for a particular user via a 
PerlSetVar in the httpd.conf script. Rather than duplicate code, for 
each user a module is used, but the variables belong to the user. One 
could write a lot of code to pass the variables into the module for 
EACH subroutine called from the handler, but the AUTOLOAD trick and 
passing the caller name make for a very compact piece of user code. 
Basically all that is there is an init routine which is only used if 
the user calls his handler from user space and the AUTOLOAD piece 
which is used by both the user and Apache. 

The module is 600 lines of perl ~ 16kb containing 20 subroutines, 
each with differing variable requirements. 
The whole user handler consists of the code below which allows the 
Module free access to all of the variables in the users handler 
space by virtue of knowing the "caller" name.

package user32::Access;
use Common::Access;
use vars qw($LogSerial %var @ISA);
@ISA = qw(Common::Access);
my $acc = 'Common::Access';

# a bunch of variables here
use constant BLAH1 => 
{VAR1 =>'some stuff',
 VAR2=> 'more stuff'
};
use constant var => \%var;

#####################################
# package reference, called only from user space
#
sub pkg {
  my ($proto) = @_;
  my $class = ref($proto) || $proto;
  my $self  = {};
  bless ($self, $class);
  return $self;
}

#####################################
# autoload extensions from 'ACCESS package'
#
sub AUTOLOAD {
no strict;
  my @sub = split('::', $AUTOLOAD);
  my $sub = $sub[$#sub];
  return undef unless $subroutine;
  return $acc->{$sub}(__PACKAGE__,@_);  # execute remote sub
}

1;
Michael@bizsystems.com

Re: how to do this??

Posted by Perrin Harkins <pe...@primenet.com>.
On Thu, 2 Nov 2000, Michael wrote:
> #handler
> package MyHandler;
> 
> use Module qw(sub1 sub2);
> use Apache;
> use vars qw(@ISA)
> @ISA = qw (Module Apache);
> 
> calling sub1 from apache
> using THIS handler named "MyHandler" results in Module::sub1 
> identifing the "caller" as Apache.

Okay, I'll bite... Why do you want to change the caller?  I mean, Apache
really is the caller if this is being invoked directly in response to a
request.

Your AUTOLOAD trick will effectively change the caller, but it will also
slow things down.  Also, exporting subs chews up some memory and should be
avoided if possible.  Using fully-qualified names is the simplest way
around it.

- Perrin