RE: Help: Can't use string ("Exchange::Account::My") as a HASH ref while "strict refs" in use trying to use instance variables in my handler
> > Anyway, what you should do is create a constructor: > > > > sub new { [snip] > > You mean like this code segment that I included in my original post > just below the handler code :) > > sub init { [snip] Ah yes, but you called your's "init", which is quite misleading to those of us who tend not to pay attention. > Wait a second. I have a startup.pl, and inside that I have the lines: > > use Exchange::Account::My; > my $account_interface = Exchange::Account::My->init; > > Won't that do what I need it to do? When the root process forks off > children, won't a complete copy of $account_interface go with it, with > everything all set and ready to go? > I wouldn't think that this would be the case, but I may be mistaken. Since you've declared $account_interface with 'my', that variable should only be available within the scope of the startup.pl script. Even if you went with use vars qw($account_interface); I still don't think that it would be available in the Exchange::Account::My namespace. > Except for calling the contructor with every call of the handler, > I think I've done everything right. Isn't the part of idea behind > mod_perl handlers that one _doesn't_ have to call the contructor > _every_ time the handler gets called? Otherwise invites massive > overhead. Is a bless really massive overhead? I can't say as I've ever had a problem calling the constructor with every request (at least with simple objects). > Obviously, what I'm doing doesn't work. But could someone show me > how to call the constructor just once in in a childs lifetime? startup.pl is not the place to do this - it gets called at server start-up (or restart), not child initialization. What you could do is create a ChildInitHandler for this class, which sets a global variable within your package: use vars qw($SELF); sub configure { my ($class) = shift; Apache->push_handlers( PerlChildInitHandler => sub { # use that weird "init" constructor name $SELF = $class->init(@_); } ); } You can then change your handler to not use the $$ prototype, but get an object reference from $SELF: sub handler { my $q = shift; my $self = $SELF; # the rest of your code as is... } In your startup.pl, you'd have: use Exchange::Account::My; Exchange::Account::My->configure(); I haven't tested that. As I said, I've never had call to create the object only upon child initialization. I'll be the first to admit that I'm relatively new to the mod_perl thing, so there may be an easier or more elegant way to do this, but that ought to work. Hope that helps. Chris
Re: Help: Can't use string ("Exchange::Account::My") as a HASH ref while "strict refs" in use trying to use instance variables in my handler
> Anyway, what you should do is create a constructor: > > sub new { > my $class = shift; > my $self {@_}; > bless $self, $class; > return $self; > } You mean like this code segment that I included in my original post just below the handler code :) sub init { my $invocant = shift; my $class = ref ($invocant) || $invocant; my $self = {}; bless ($self, $class); $self->{config}= $self->init_config; $self->{dispatch} = $self->init_dispatch_table; $self->{templates} = $self->init_templates; $self->{_child_started_up} = 0; return $self; } ... straight out of "Programming Perl" ... > > Then rewrite the above snippet of your code to: > > sub handler ($$) { > my ($class, $q) = @_; > my $r = Apache::Request->new($q); > my $self = $class->new(request=>$r); Hunh?!? Wait a second. I have a startup.pl, and inside that I have the lines: use Exchange::Account::My; my $account_interface = Exchange::Account::My->init; Won't that do what I need it to do? When the root process forks off children, won't a complete copy of $account_interface go with it, with everything all set and ready to go? > $self->child_init unless $self->{_child_started_up}; > # The rest of the code... > > Then you should be good to go (instance variables and all!). Hope that > helps, > > Chris Except for calling the contructor with every call of the handler, I think I've done everything right. Isn't the part of idea behind mod_perl handlers that one _doesn't_ have to call the contructor _every_ time the handler gets called? Otherwise invites massive overhead. Obviously, what I'm doing doesn't work. But could someone show me how to call the constructor just once in in a childs lifetime? Please? --Christopher
RE: Help: Can't use string ("Exchange::Account::My") as a HASH ref while "strict refs" in use trying to use instance variables in my handler
> Subject: Help: Can't use string ("Exchange::Account::My") as > a HASH ref > while "strict refs" in use trying to use instance variables in my > handler [snip] > sub handler ($$) { > my ($self, $q) = @_; > > my $r= Apache::Request->new($q); > > $self->child_init unless $self->{_child_started_up}; # < dies > here! [snip] I think that you really need to have a legitimate constructor, not one that is called conditionally. $self is not a blessed reference - just a string containing the class name. The call to $self->child_init works, even with strict refs, because there is a child_init subroutine defined in your package's namespace. With $self->{_child_started_up}, you're just calling "Exchange::Account::My"->{_child_started_up}, which will cause the error since the string "Exchange::Account::My" is not a reference to a hash, it's just a string. Anyway, what you should do is create a constructor: sub new { my $class = shift; my $self {@_}; bless $self, $class; return $self; } Then rewrite the above snippet of your code to: sub handler ($$) { my ($class, $q) = @_; my $r = Apache::Request->new($q); my $self = $class->new(request=>$r); $self->child_init unless $self->{_child_started_up}; # The rest of the code... Then you should be good to go (instance variables and all!). Hope that helps, Chris