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

Hi all,
Are there many $Report variable?
My code (slighty simplified) is :
my $Report=""; sub note { my ($titre,$texte) = @_; print STDERR "*update.pl(($titre,$texte)) \n"; my $Texte= '<H5>'.$titre.'</H5><P>'.$texte.'</P>'; $Report .=$Texte; print STDERR "*update.pl:$Texte\n[\n$Report\n]\n"; } ... note($title,$text); ... print STDERR "*update.pl: end \n[\n$Report\n]\n";
My final print of $Report is sometimes empty. Moreover, in note(), the print of the value of $Report contains data of a previous excution of the script.

Please note that I run under mod_perl under Apache Linux.
I am sure that I am missing something on the memory space.

Thank you in advance.
Pierre Couderc

Replies are listed 'Best First'.
Re: Basic question
by liz (Monsignor) on Aug 20, 2003 at 09:58 UTC
    You're probably running under Apache::Registry. From the CAVEATS section of Apache::Registry:
    Apache::Registry makes things look just the CGI environment, however, you must understand that this *is not CGI*. Each httpd child will compile your script into memory and keep it there, whereas CGI will run it once, cleaning out the entire process space.

    I wouldn't be surprised if my $Report is a package lexical, which only gets initialized once. And from then on keeps its value between requests.

    I haven't used Apache::Registry myself ever, but I think you can solve this by putting your code in a block, like this:

    { my $Report = ""; ... yada yada yada print STDERR....; }

    This will ensure that $Report will get initialized properly each request.

    This is untested, so YMMV.

    Liz

        Thank you Valerio, thank you all.
        This (my() Scoped Variable in Nested Subroutines)is the explanation.
        I am under Apachel::Registry, ans using diagnostics, I have put in evidence that :
        Variable "$Report" will not stay shared at .../update.pl
        Thank you all again.
        Pierre

      You can fix it with a BEGIN block, but not with a plain block.

                      - tye
Re: Basic question
by Abigail-II (Bishop) on Aug 20, 2003 at 09:49 UTC
    From the code fragment you posted, it's not possible that $Report is sometimes empty.

    Could you create a small, clear, stand alone piece of code that exhibits the unwanted behaviour? Now there are too many unknowns, and I'm not going to guess what might be wrong.

    Abigail

      Thank you, Abigail.
      Are you sure of you? That is, are you sure that under mod-perl it is not possible that $Report be empty? My idea is that the scope of the variables could be different between the "main" and note()? And this, not in standard perl but in mod-perl.
      Pierre
        Of course it's possible that the scope of main and note is different. That's why I asked you to write a stand-alone piece of code, and not a piece of code where we have to fill in the blanks.

        If you leave out the "...." in your code, it's impossible that $Report is empty, except for some bug in the implementation.

        Abigail

Re: Basic question
by pcouderc (Monk) on Aug 20, 2003 at 16:35 UTC
    Thank you to all. I give my final solution, that seems to work as it could be useful for another one.
    $main::Report=""; sub note { my ($titre,$texte) = @_; print STDERR "*update.pl(($titre,$texte)) \n"; my $Texte= '<H5>'.$titre.'</H5><P>'.$texte.'</P>'; $main::Report .=$Texte; print STDERR "*update.pl:$Texte\n[\n$main::Report\n]\n"; } ... note($title,$text); ... print STDERR "*update.pl: end \n[\n$main::Report\n]\n";