http://www.perlmonks.org?node_id=756109

bradcathey has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monasterians,

I've posted several questions about CGI::Session over the past months, but they have all been different issues. Here's a new one that I've distilled it down to the code below.

Question: Why is the value of a param not get past the subroutine that sets it?

my $logged_in = write_session( $user ); print Dumper($logged_in, $session->param('user')); sub write_session { my $user = shift; my $session = new CGI::Session(); $session->param('user' => $user); $session->param('logged_in' => 1); my $cookie = $query->cookie( CGISESSID => $session->id ); #print $query->header(-cookie => $cookie); print $session->header(-cookie => $cookie); #$session->flush() return ($session->param('logged_in')); } ---------- DUMPER ------------ $VAR1 = 1; $VAR2 = undef;

You can see that I test for the successful setting of the param in the routine, but it returns undef when I am back in the calling module. Note: the cookie is set and a session id generated. A cat of the actual session file in /tmp shows everything is there before I try to read it. And you can see I tried flush() and setting the cookie directly, all to no avail.

I use CGI::Application::Plugin::Session in newer projects, which has lazy loading (not initiated until called), but this doesn't seem to be the same deal). I've read the lovely CGI::Session::Tutorial several times, but no approach seems to work. Thoughts?

—Brad
"The important work of moving the world forward does not wait to be done by perfect men." George Eliot

Replies are listed 'Best First'.
Re: Value for session set in CGI::Session is undef
by moritz (Cardinal) on Apr 07, 2009 at 19:14 UTC
    You have two independent $session variables, each holding a different CGI::Session object. One in the outer scope, one declared with my in the subroutine.

    Now you change something in the session object in the subroutine, and expect that change to get magically transferred to the outer session object as well. It won't. They are independent objects.

Re: Value for session set in CGI::Session is undef
by lostjimmy (Chaplain) on Apr 07, 2009 at 19:16 UTC

    I'm not exactly sure what your problem is, but I do have a couple of things to point out.

    • CGI::Session::header automatically sends the CGISESSID cookie for you, so you don't have to get the cookie and send it yourself.
    • Where has $session been defined in this part of code: print Dumper($logged_in, $session->param('user'));? How can you expect that $session object to have the changes you made in write_session? I would think that if you've created a session object, then created a new, lexically scoped session object within your subroutine, that upon return, the first object would not contain the updates that you made.
    • Would it make more sense to pass $session to write_session, rather than creating a new one?
Re: Value for session set in CGI::Session is undef
by VinsWorldcom (Prior) on Apr 07, 2009 at 19:51 UTC

    In your "main program", you call:

    print Dumper($logged_in, $session->param('user'));

    But, $session isn't defined. It is defined (with "my" and the the "new CGI::Session()" call in the subroutine) and not passed back.

    Try doing the $session = new... call in the main program and passing both the $session and $user variables to the sub.

      Every poster was correct pointing out that $session was not defined in my calling program. Duh!

      So, I tried this first:

      my $logged_in = write_session( $user ); my $session = CGI::Session->load(); print Dumper($logged_in, $session->param('user'));

      which I thought would be the proper way to do it, but ended up following your advice with:

      my $session = new CGI::Session(); my $logged_in = write_session( $session, $user ); print Dumper($logged_in, $session->param('user'));

      which did the trick. Thanks.

      —Brad
      "The important work of moving the world forward does not wait to be done by perfect men." George Eliot