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

Hi Monks
I can't believe that this answer is hard to find.

In command line invoked perl "time" will return the time in epoch seconds (each and every time).

In my mod_perl code (execution invoked by a browser hit) a line such as "$t = time;" only updates the first time after a script change or apache2 reset. This makes some sense based upon my limited reading of the advantages of mod_perl. But, how do I force my code to give me the CURRENT AT EXECUTION TIME value of the time (in epoch seconds).

Thank you,
Bruce

Replies are listed 'Best First'.
Re: time in mod_perl
by ikegami (Patriarch) on Mar 27, 2007 at 19:01 UTC

    I bet you're using an Apache::Registry script with a global my variable.

    my $t = time; sub print_t { print("$t\n"); } print_t(); print("$t\n");

    This is not a mod_perl problem, but an Apache::Registry problem. Apache::Registry puts your script in a function it executes every time the page is requested.

    my $script = sub { my $t = time; sub print_t { print("$t\n"); } print_t(); print("$t\n"); }; $script->(); # A page request sleep(2); $script->(); # A page request

    the problem is that print_t closed over $t, so it always refers to $t original value, even though $t changes.

    1175021938 1175021938 1175021938 <- print_t still references the original $t 1175021940

    The fix is to use package variables instead of lexical variables for globals in Apache::Registry scripts.

    my $script = sub { our $t = time; sub print_t { print("$t\n"); } print_t(); print("$t\n"); }; $script->(); # A page request sleep(2); $script->(); # A page request
    1175022050 1175022050 1175022052 1175022052
      I did a little Googling on "our" vs. "my". I found some material but I am not quite catching the drift. Is there an easy explination of "our" vs. "my" in the context of mod_perl programs running on Apache2?

      Thank you,
      Bruce

        Sometimes it's better to use the pm search rather than the google search (although, I understand that's changing).

        If you search on pm for doc://my and doc://our you'll get redirected to nicely colored pages at perldoc.perl.org. The document on our explains the difference quite nicely (if esoterically). I actually use this search engine in firefox as much as I don't.

        -Paul

      Also, I am getting "will not stay shared" messages in my Apache error log for both the time variable that I have "fixed" and the other variables. This error message seems to be the same scope issue we have been dealing with in this posting. This scope issue (my lack of mastering it) seems to be filling my error log up with lots of useless messages. This makes it harder to notice a useful error message. What can I do to keep my error log clean?

      Thank you,
      Bruce
Re: time in mod_perl
by jettero (Monsignor) on Mar 27, 2007 at 18:50 UTC

    It's hard to find because it's hard to know how to phrase the question. I suspect it's a scoping issue. The mod_perl environment is sometimes a little surprising in that respect. If you post some of the code it'd probably be a lot easier to figure out.

    My initial guess is that you're using Apache::Registry in a way that exposes you to closures by accident. I first started with mod_perl by converting existing CGIs into mod_perl apps with a handler like this:

    # <Files ~ ".pl$"> # SetHandler perl-script # PerlHandler Apache::Registry # </Files>

    If I recall correctly, it was wrapping my whole .pl file in a big function and causing strange things to happen. I got the hang of it after a while, but not until I read things like Closures and scope, Closures question, and more.

    I had a bunch of nice articles bookmarked that explained the problem really well, but they seem to have disappeared on me. ikegami explains it really well below anyway.

    -Paul

      I'm looking through this scope response and the following Apache::Registry response. Both look very interesting and it's nice to have a suggestions to think about rather than just hitting my head on the wall some more.

      My program is 20+ pages and most of it contains material I can not post. I took a few minutes to write a test program and I can not (yet) explain why my test program DOES WORK and my main code does not. Chances are, one of these two responses has the answer.

      My small test code that DOES WORK is:
      #!/usr/bin/perl # FILE: test_time_01.pl use warnings; use strict; use CGI qw(:standard escapeHTML); my $t = time; print start_multipart_form(-action => url()), p header(), start_html("test"), p ("The value of time is $t. &lt;br&gt;&lt;br&gt;"), end_form();

      Thank you,
      Bruce

      Edit: g0n - code tags

        Right, it's like ikegami says then. That my $t = time isn't really in the global scope like you'd imagine. It's wrapped in a function ref that's stored in the handler (or something close to that).

        -Paul

        Thank you to everyone.

        When I pass my time variables to the subroutines it seems to work. Thus, it is a scope issue. I still don't know if there is a deeper wisdom here that I should be seeking or if I should just pass all variables with mod_perl and move on. Either way, I am back on track for this project.

        Thank you,
        Bruce

Re: time in mod_perl
by Joost (Canon) on Mar 27, 2007 at 18:49 UTC
Re: time in mod_perl
by Elijah (Hermit) on Mar 27, 2007 at 19:18 UTC
    it is a scoping issues, mod_perl is funny about such things for persistent db connections and whatnot. To overcome this and have a somewhat global variable be re-assigned with each page load you will need to scope your variable assignment.

    use vars qw($var1 $var2 $var3); { $var1 = 'One'; $var2 = 'Two'; $var3 = 'Three'; }
    or:

    use vars qw($var1 $var2 $var3); initialize(); sub initialize { $var1 = 'One'; $var2 = 'Two'; $var3 = 'Three'; }
    Have to scope the assignment somehow to tell mod_perl you want to re-assign and not keep persistent.