Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^3: Subclassing Apache::Request?

by perrin (Chancellor)
on Aug 11, 2004 at 05:33 UTC ( [id://381876]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Subclassing Apache::Request?
in thread Subclassing Apache::Request?

What you are failing to understand here is that your handler is not an object, it is just a class. In fact, it's not even called as class unless you tell mod_perl to use method handlers, which you haven't done here. In the examples in the docs, someone subclasses Apache::Request and then instantiates an object like this:
my $apr = My::Apache::Request::Subclass->new($r);
That is not what happens when mod_perl calls your handler. It doesn't call new, since new() is not a special method in Perl. It calls handler (well, you could tell it to call something else, but it's not important), passing an Apache::request object (note the lowercase r) as the only parameter. This object is normally referred to as $r, and it's the same thing you get by calling Apache->request().

At this point, you can create an Apache::Request object by passing $r to Apache::Request->new(), or instantiate a subclass of Apache::Request in the same way. You can even make it so that other people will get your subclass object when they call Apache->request() by calling it as a set method:

Apache->request($apr);
However, there is almost never a good reason to subclass Apache::Request and I don't understand why you think this will help with your session management woes. Apache::Request has nothing to do with session management. It only exists for the current request and nothing in it is saved when it goes away. So, please explain what you are really trying to do, and maybe I can suggest a better solution.

Replies are listed 'Best First'.
Re^4: Subclassing Apache::Request?
by tadamec (Beadle) on Aug 11, 2004 at 08:31 UTC

    I think the problem I was having was my understanding of exactly how mod_perl works. I've been operating under the assumption that I was getting an Apache::Request object when this, clearly, is not the case. Up until now, the distinction hasn't mattered, as I've been able to just treat the reference passed into the handler as an "object" and everything is fine.

    What I'm running into now is trying to organize the ball of mud that the application has become. We have a set of application handlers that the actual Apache handler calls based some URI formatting rules. For example, the URI www.example.com/Foo/bar will instantiate a copy of a Foo object, call the bar method and pass the resulting values back to an instance of the Template Toolkit for display.

    The problem comes into being when that object needs to forward calls to successive methods. For example, say the bar method needs to do some input validation and store the validated input for passing into the baz method.

    We have no consistent methodology for doing this at the moment, other than the requirement that the tied hash of an Apache::Session object is passed into every method. We have some objects that will put the data they need into a named hashref underneath the session like so:

    $SESSION->{Foo} = { Value => 94, name => 'Frank' }
    While others will do the following:
    $SESSION->{value} = 94; $SESSION->{name} = 'Frank';
    Where I run into bigger problems is when code uses a key like "validate". Some of the authentication code uses "validate" to insure that the user is logged in, while other functions set a "validate" key to mean that the variables have been validated. We have masses of special case if statements throughout the application to move these "magic" tokens around so we don't break other functionality. Obviously, it's a nasty situation that needs to be refactored.

    My thinking was that I could subclass Apache::Request, place my session handling code within the subclass, and add a couple of methods to do things like add an application global setting, and a couple of helper functions for adding the object specialized stuff, above. Perhaps something like this:

    # Set a global "login" variable $r->set_global( Login => 1 ); # Do some other stuff, then let the Bar function do things. $r->private_variable( Package => "Foo", Function => "Bar", Value => "S +ome Value" );
    This needs a bit more refinement, obviously, but I think it would solve some of our problems.

    I'm imagining a set of functions that are easy to work with and make accessing values stored between requests logical instead of the chaotic approach that the application currently uses.

    Is that a better explaination?

      Okay, there's something like this already there. For values that should be accessible anywhere during the life of the current request, you can use $r->pnotes(). It's just like a hash:
      my $r = Apache->request(); # or grab it when passed to handler $r->pnotes( Login => 1 ); my $foo = $r->pnotes( 'foo' );
      The pnotes() values only last for the length of the current request and get cleaned up automatically at the end of it. I'm not quite sure what you were trying to do with your provate_variable call, so I can't suggest anything there.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://381876]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2024-03-29 15:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found