in reply to 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)

Hmm... it's an idea. But really, I'm not going to be using My::Hash::Tie::Class. I'll be working with Apache::Session or Apache::SessionX. (That was meant to be a metasyntactic class name variable.)

I could end up subclassing either to My::ApacheSessionRipOff and implement things this way I suppose, but hopefully that will be my second option on how to proceed, and not my only one.

Cheers,
Richard

  • Comment on Re: Re: Given a tie object, get a tied hash (or scalar, or whatever)

Replies are listed 'Best First'.
Re: Re: Re: Given a tie object, get a tied hash (or scalar, or whatever)
by perrin (Chancellor) on Aug 13, 2003 at 15:54 UTC
    Can you explain what you're trying to do with Apache::Session? There might be another way.
      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.

Re^3: Given a tie object, get a tied hash (or scalar, or whatever)
by adrianh (Chancellor) on Aug 13, 2003 at 19:13 UTC
    But really, I'm not going to be using My::Hash::Tie::Class. I'll be working with Apache::Session or Apache::SessionX. (That was meant to be a metasyntactic class name variable.)

    Ah. In that case something like this will probably do the trick (untested code):

    package Tie::WrapUsing; sub TIEHASH { my ($class, $object) = @_; return $object; }; package main; use Test::More tests => 2; use Apache::Session::File; my $object = tie my %orig, 'Apache::Session::File', undef, { Directory => '/tmp' }; tie my %dupe, 'Tie::WrapUsing', $object; $orig{foo}=42; $dupe{bar}=24; is $dupe{foo}, 42, 'change in original reflected in duplicate'; is $orig{bar}, 24, 'change in duplicate reflected in original';

    However, your real problem seems to be that you want to use a tied hash as an object - which kind of defeats the purpose :-) If I were you I'd use an object-based session system like Cache::Cache instead.