First and foremost, I'm wet behind the ears when it comes to OOPerl and lack confidence in my class design decisions. Any advice and or guidance is GREATLY appreciated. I have been studying Damian Conway's book and various other resources ... but have a distance to travel before I'm comfortable.
I'm currently integrating Apache::Session::MySQL into an existing project. I've created a (very simple) Session class that uses Apache::Session::MySQL giving me a singular connection to my data store, etc.
My questions in regard to my class are...
- Am I wasting my time creating a session class on top of Apache::Session::MySQL when the only true benefit at this point is the singular data store connection? What other abilities are common in such custom “Session” classes?
- How can I improve the data-structure of my resulting object? I feel as though blessing an anonymous hash and using a single key to point to a reference to a tied %session hash is wasteful. (ie: $self->{session} = \%session).
- Is "init" an appropriate location to handle the interface with Apache::Session?
- Should I be taking steps to protect my session data such as a closure? From my script I am able to do the following: my $id = $session_obj->{session}->{_session_id} – this defeats the point of OOP!
- Is it necessary to "untie" my %session hash when closing (not deleting) the session?
Below is a link to my class code. The class functions as expected but I know it can be improved upon greatly. There are several parts of the class structure that I am not happy with which I have noted in the code.
package Local::SessionClass;
use warnings;
use strict;
use Apache::Session::MySQL;
sub new {
my ($class, %args) = @_;
my $self = bless {}, ref($class) || $class;
$self->init(%args);
return $self;
}
sub init {
my ($self, %args) = @_;
my $id = $args{id} || undef;
my %session;
tie %session, 'Apache::Session::MySQL', $id, {
Handle => $args{dbh},
LockHandle => $args{dbh}
};
# I FEEL AS THOUGH THE USEFUL DATA (%session) IS NEEDLESSLY REMOVED
+ FROM THE OBJECT'S MAIN DATA STRUCTURE (ITS ANONYMOUS HASH) REQUIRING
+ ME TO DEREF MULTIPLE REFERENCES.
$self->{session} = \%session;
return;
}
sub get_sid {
my $self = shift;
# AS MENTIONED ABOVE ... MULTIPLE DEREF
return $self->{session}->{_session_id};
}
# THIS SUB ALLOWS ME TO PASS IN MULTIPLE KEY=>VAL PAIRS FOR STORAGE PU
+RPOSES
sub set_sdata {
my ($self, %args) = @_;
map{$self->{session}->{$_} = $args{$_}} keys %args;
return;
}
sub get_sdata {
my $self = shift;
return %{$self->{session}};
}
# DELETE A KEY=>VAL FROM THE TIED %SESSION HASH
sub delete_sdata {
my ($self, $key) = @_;
delete $self->{session}->{$key};
return;
}
# SIMPLY UNTIE THE SESSION FOR CLEAN UP ... IS THIS NECCESSARY?
sub close_session {
my $self = shift;
untie($self->{session});
}
# MANUALLY KILL THE SESSION ON LOGOUT
sub kill_session {
my $self = shift;
tied(%{$self->{session}})->delete;
untie($self->{session});
return;
}
# CLEAN UP UPON EXIT
sub DESTROY {
my $self = shift;
$self->close_session;
}
1;
### CREATE A NEW SESSION - CALLED FROM LOGIN SCRIPT ###
use Local::SessionClass;
# CREATE SESSION ID
my $session_obj = Local::WPSession->new(dbh => $dbhandle);
my $session_id = $session_obj->get_sid();
# ... SET COOKIE WITH SESSION ID ...
# SET SESSION VALUES
$session_obj->set_sdata(
val_1 => 'foo',
val_2 => 'bar'
);
### RELOAD EXISTING SESSION - CALLED FROM SEPARATE SCRIPTS ###
use Local::SessionClass;
my $session_id = $q->cookie(-name => 'previously_set_cookie');
my $session_obj = Local::WPSession->new(dbh => $dbh, id => $session_id
+);
# ACCESS SESSION VALUES
my %sdata = $session_obj->get_sdata();
Thank you ahead of time for your help and advice. If any explanation is needed beyond what I have provided above, please just ask and I will respond immediately.
UPDATE: Added <readmore></readmore> tags.