From: tim on
Hello

I'm new here, so, hi!

I've been having the following problem. I have a module which I am
creating to manage sessions for my website. I have the following sub in
it:

#takes an active db handle, returns a new session object.
sub newSession {
my $dbh = @_[1];
my %session;
tie %session, 'Apache::Session::MySQL', undef,
{ Handle => $dbh,
LockHandle => $dbh};
print "Session session ref = ". \%session . "\n";
return \%session;
}

In the calling routine, I have the following code:

my $sessionref = SessionManager->newSession($dbh);
my %session = %$sessionref;
tied(%session)->delete;

The first two lines seem to work ok, but the 3rd gives this error:

Can't call method "delete" on an undefined value at ./tester line 31.

Bizarely, it seems I can access the object in other ways from the same
context, as the following lines work as expected:

print "session id = $session{_session_id}\n";
print "testing session ref = " . $sessionref . "\n";

(i.e. session id is printed)

I'd really appreciate any comments or suggestions on why the above may
be occuring.

Many thanks

Tim.

From: Paul Lalli on
tim wrote:

> I'm new here, so, hi!

Welcome! Please make sure you read the Posting Guidelines for this
group (posted here twice a week) to learn valuable tips to maximize the
potential usefulness of posting here...

> I've been having the following problem. I have a module which I am
> creating to manage sessions for my website. I have the following sub in
> it:
>
> #takes an active db handle, returns a new session object.
> sub newSession {
> my $dbh = @_[1];

Always always always use warnings when devleoping Perl code. This
should have told you:
Scalar value @_[1] better written as $_[1]

> my %session;
> tie %session, 'Apache::Session::MySQL', undef,
> { Handle => $dbh,
> LockHandle => $dbh};
> print "Session session ref = ". \%session . "\n";
> return \%session;
> }
>
> In the calling routine, I have the following code:
>
> my $sessionref = SessionManager->newSession($dbh);
> my %session = %$sessionref;

%session is a brand new hash, simply populated with the values that are
currently in the variable %$sessionref. It is in all other ways
unrelated to $sessionref. It is not tied to any object of the
Apache::Session::MySQL class.

> tied(%session)->delete;
>
> The first two lines seem to work ok, but the 3rd gives this error:
>
> Can't call method "delete" on an undefined value at ./tester line 31.

Because %session is not a tied variable, tied() returns undef.

>
> Bizarely, it seems I can access the object in other ways from the same
> context, as the following lines work as expected:
>
> print "session id = $session{_session_id}\n";

_session_id is one of the keys you copied over when you created the new
hash, so yes, that works.

> print "testing session ref = " . $sessionref . "\n";
>
> (i.e. session id is printed)

$sessionref is a reference to the original tied variable, so yes, that
works.

> I'd really appreciate any comments or suggestions on why the above may
> be occuring.

Copying a hash does not copy the tied nature of the variable.

Paul Lalli

From: tim on
Thanks Paul

Whoops- didn't notice that warnings were off. I'll make sure they're on
before posting next time!!

Tim

Paul Lalli wrote:
> tim wrote:
>
> > I'm new here, so, hi!
>
> Welcome! Please make sure you read the Posting Guidelines for this
> group (posted here twice a week) to learn valuable tips to maximize the
> potential usefulness of posting here...
>
> > I've been having the following problem. I have a module which I am
> > creating to manage sessions for my website. I have the following sub in
> > it:
> >
> > #takes an active db handle, returns a new session object.
> > sub newSession {
> > my $dbh = @_[1];
>
> Always always always use warnings when devleoping Perl code. This
> should have told you:
> Scalar value @_[1] better written as $_[1]
>
> > my %session;
> > tie %session, 'Apache::Session::MySQL', undef,
> > { Handle => $dbh,
> > LockHandle => $dbh};
> > print "Session session ref = ". \%session . "\n";
> > return \%session;
> > }
> >
> > In the calling routine, I have the following code:
> >
> > my $sessionref = SessionManager->newSession($dbh);
> > my %session = %$sessionref;
>
> %session is a brand new hash, simply populated with the values that are
> currently in the variable %$sessionref. It is in all other ways
> unrelated to $sessionref. It is not tied to any object of the
> Apache::Session::MySQL class.
>
> > tied(%session)->delete;
> >
> > The first two lines seem to work ok, but the 3rd gives this error:
> >
> > Can't call method "delete" on an undefined value at ./tester line 31.
>
> Because %session is not a tied variable, tied() returns undef.
>
> >
> > Bizarely, it seems I can access the object in other ways from the same
> > context, as the following lines work as expected:
> >
> > print "session id = $session{_session_id}\n";
>
> _session_id is one of the keys you copied over when you created the new
> hash, so yes, that works.
>
> > print "testing session ref = " . $sessionref . "\n";
> >
> > (i.e. session id is printed)
>
> $sessionref is a reference to the original tied variable, so yes, that
> works.
>
> > I'd really appreciate any comments or suggestions on why the above may
> > be occuring.
>
> Copying a hash does not copy the tied nature of the variable.
>
> Paul Lalli

From: Mumia W. (reading news) on
On 09/27/2006 07:08 AM, tim wrote:
> Hello
>
> I'm new here, so, hi!
>
> I've been having the following problem. I have a module which I am
> creating to manage sessions for my website. I have the following sub in
> it:
>
> #takes an active db handle, returns a new session object.
> sub newSession {
> my $dbh = @_[1];
> my %session;
> tie %session, 'Apache::Session::MySQL', undef,
> { Handle => $dbh,
> LockHandle => $dbh};
> print "Session session ref = ". \%session . "\n";
> return \%session;
> }
>
> In the calling routine, I have the following code:
>
> [29:] my $sessionref = SessionManager->newSession($dbh);
> [30:] my %session = %$sessionref;
> [31:] tied(%session)->delete;
>

The hash is no longer tied to 'Apache::Session.' Line 30 makes a /copy/
of the tied hash returned by newSession(). However, the tying does not
survive the copying, so $sessionref is still tied, but %session is not,
so the "tied" function returns undef for %session.

> The first two lines seem to work ok, but the 3rd gives this error:
>
> Can't call method "delete" on an undefined value at ./tester line 31.
>

It's the same as saying that this is invalid:
undef->delete();


> Bizarely, it seems I can access the object in other ways from the same
> context, as the following lines work as expected:
>
> print "session id = $session{_session_id}\n";
> print "testing session ref = " . $sessionref . "\n";
>
> (i.e. session id is printed)
>

Try this:

tied(%$sessionref)->delete();


> I'd really appreciate any comments or suggestions on why the above may
> be occuring.
>
> Many thanks
>
> Tim.
>

You're welcome.

--
paduille.4058.mumia.w(a)earthlink.net
From: Mirco Wahab on
Thus spoke tim (on 2006-09-27 14:08):

> I'm new here, so, hi!

Great!

> #takes an active db handle, returns a new session object.
> sub newSession {
> my $dbh = @_[1];

Shouldn't the @_[1], which is
a array slice containing the
*second* argument of the caller,
read: $_[0] ... ?

> my $sessionref = SessionManager->newSession($dbh);
> my %session = %$sessionref;
> tied(%session)->delete;

Here you drop a single argument to your function ...

(The return will be a ref to empty hash or sth.)

Regards

Mirco