in reply to Re: Re: Given a tie object, get a tied hash (or scalar, or whatever)
in thread Given a tie object, get a tied hash (or scalar, or whatever)

Can you explain what you're trying to do with Apache::Session? There might be another way.
  • Comment on Re: Re: Re: Given a tie object, get a tied hash (or scalar, or whatever)

Replies are listed 'Best First'.
Re: Re: Re: Re: Given a tie object, get a tied hash (or scalar, or whatever)
by Dice (Beadle) on Aug 13, 2003 at 16:35 UTC
    I fear that giving the complete answer to this quesiton will only show the kind of deludged curmudgeon I am.

    So I'm working on a web project. I'm working with CGI::Application. I want to use Apache::Session (or SessionX, whatever) to do my sessioning stuff. I want to retrieve my session in the setup stage, and then just haul its ass around to whatever run-modes I need via the $self.

    Now, $self->param within CGI::Application could do the job, a la:

    sub setup { my $self = shift; tie %session, 'Apache::Session', $self->query->cookie('session_id' +); $self->param('session', \%session); # etc. } sub current_run_mode { my $self = shift; # etc. my $uid = $self->param('session')->{uid}; # etc. }

    I'm willing to do this, if need be. But I like my composited objects (and their related methods) to be "first class". In this case, that means I'd rather my attempts to get session data would look like:

    my $uid = $self->session->uid;

    How would I do this? (Rhetorical question.) I have already subclassed CGI::Application to My::CGIApplication that gives me 1st class object composition capabilities, like this:

    sub setup { my $self = shift; tie %session, 'Apache::Session', $self->query->cookie('session_id' +); $self->composite_object( name => 'session', object => tied(%session)); # etc. }

    This gives me calls like $self->session. So now I need to get at the session data in a first class way. (Obviously I could get at it in a 2nd or 3rd class way such as $self->session->FETCH('uid'), but I don't like the smell of this.)

    So, this leads me to subclassing Apache::Session. Consider My::ApacheSession which has within it this...

    sub AUTOLOAD { my $self = shift; my $attribute = $AUTOLOAD; $method =~ s/.*:://; if ( length($method) != 0 ) { if ( @_ > 1) { return $self->STORE($attribute, @_); } else { return $self->FETCH($attribute); } } else { croak "No such object attribute referenced by name '" . $attribute . ' to provide "; } }
    So this is entirely doable. However, I would like it cleaner (i.e. forgetting about FETCH and STORE). So refer back to my original posting...
    sub AUTOLOAD { my $self = shift; my $attribute = $AUTOLOAD; $method =~ s/.*:://; my %session = Foo($self); if ( @_ > 1) { return $session{$attribute} = $_[0]; } else { return $session{$attribute}; } }
    So that's all. Hope with all that wind-up it wasn't an anticlimax. Perrin, as you said, there is another way. I was just hoping that the way I wanted to do things exists, too.

    Cheers,
    Richard

      I think you're making this way too hard. Apache::Session is meant to be used as tied hash, not as an object, and if you want to use it as an object you should really just get over your dislike of FETCH/STORE and use them directly. The extra levels of indirection here just aren't worth it in my opinion.

      If you really want an OO Apache::Session, I'd suggest you just hack the Apache::Session code to do what you want. I've frequently had to hack it to do things I need that aren't in there. It's not sacred code, and given how rarely it gets updated you won't have much cause for concern with future versions.