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

I'm coming from an OO background and had a question about keeping a persistent variable. For those familar with java, you know that you can instantiate a class and have variables associated with that class that you can assign and retrieve values for.
Here's the perl question. I have a main script that checks the cgi params and calls subroutines according to the params. Each subroutine outputs html code that includes the users sessionid and username. Can I have a perl package that would keep track of the username sessionid so that I could reference there values in my subroutines? Or do I have to pass the values, of the sessionid and username to each of the subroutines when I call them.
I was envisioning something like this.
package Common; { my $username,$sessionid; } ### #set their values in the main code $comm=new Common; $comm->$username=user; $comm->$sessionid=1234; subone($comm); #in subroutines i could call subone { print "$comm->$username"; }
Is there a practical way of doing this? Anyway to do it without even having to pass the $comm to the subroutines?
Thanks.

Replies are listed 'Best First'.
Re: Persistent Variable
by Fastolfe (Vicar) on Jan 15, 2001 at 22:24 UTC
    I think you're headed in the right direction. Typically the best way to implement something like this is to pass around a single variable reference (either an object or a hash reference are common) with all of your state information.
    my $state = { username => $username, sessionid => $sessionid, whatever => $else, }; &one($state, $other_args); &two($state, @more); &three($state);
    Another way of doing this is to turn $state into an object, and turn one, two and three into object methods.
    $state = new Object($username, $sessionid); $state->one($other_args); $state->two(@more); $state->three;
    I kind of like things like Class::Struct for defining a simple object-ish representation of a data structure like that, which is easy to pass around as a single unit.
      Okay, I was thinking of creating a package "Common" that would hold the state variables. Can you "set" a variable in a package and be able to retrive it later if you maintain the pointer to the package? For instance..
      package Common; my $session; #main program $comm=new Common; $comm->session="1234"; $temp=$comm->session; print "$temp";
      would this print out 1234 or can you not assign variables inside packages like this? Thanks.
        $Common::variable = "value"; print $Common::variable; # 'value'
Re: Persistent Variable
by Adam (Vicar) on Jan 15, 2001 at 22:42 UTC
    First off, if you are already comfortable with OO thinking, then you might want to check out Perl's OO. Its not as solid as Java or C++, but it is there. (perltoot is a good tutorial.)

    Ok, on to your question:
    You don't need a separate package for these variables. If you declare the variables in your script before declaring any subs then all the subs in main:: can see them. If you have them in a namespace other then main::, then you'll either want to use our (5.6+) or use vars($^V<5.6)

    #!perl -w use strict; #Always! my $username=user; my $sessionid=1234; subone($comm); #in subroutines i could call subone { print "$comm->$username"; }
      It may not have been clear from my original post, but the subs themselves are in different package, that are being called by main, so they variables wouldn't be seen if I just declared them as globals.
        Actually, that's what I meant when I said, "If you have them in a namespace other then main::, then you'll either want to use our (5.6+) or use vars($^V<5.6)." With out playing games with the import() method or Exporter, you can get to package globals by fully specifying the package name. ie:
        use strict; # I can't emphasize that enough! { package Common; use vars qw/ $Var1 @Var2 /; $Var1 = "some value"; @Var2 = ( 1, 2, 3); if( $^V =~ m/^5\.6/ ) { our $Var3 = "The 5.6 way to do the above"; } } # Now in main:: name space print $Common::Var1; print reverse @Common::Var2;
Re: Persistent Variable
by InterGuru (Sexton) on Jan 15, 2001 at 23:58 UTC
A reply falls below the community's threshold of quality. You may see it by logging in.