Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Possible to refer to variable defined later in script?

by jaffinito34 (Acolyte)
on Nov 12, 2012 at 15:48 UTC ( #1003468=perlquestion: print w/replies, xml ) Need Help??
jaffinito34 has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to print to the top of an HTML file how many unique visitors the page has gotten. However, the variable does not get defined until later in the script. See below.

# CSC 310 Project # 4 #opening log and html file open (LOG, '<', 'IN-access.log'); open (HTML, '>>', 'OUT-access.html'); #printing header/title/format of html print HTML "<HTML><TITLE>Visitors Log</TITLE><BODY>\n"; print HTML "The log file start date is: date() <BR>\n"; print HTML "There were $IPcount unique visitors in the logfile.<BR>\n" +; print HTML "There were 2 visits yesterday<BR>\n"; print HTML "<TABLE border=1><TR><TD>IP</TD><TD>LOGFILE</TD></TR>\n"; #reading log file while ($lines = <LOG>){ #keeps track of unique visitors $oldIP = $remoteIP; #assigning values ($remoteIP,$rfc,$userID,$dateTime,$timeZone,$requestType,$fileRequ +ested,$requestProtocol,$statusCode,$sizeOfFile) = split ' ', $lines; #keeps track of unique visitors if ($oldIP ne $remoteIP){ $IPcount += 1; } ....

The variable $IPcount is blank when printed into the HTML file but I was wondering if there's a way to get the value to print even though it wasn't defined until later on.

Replies are listed 'Best First'.
Re: Possible to refer to variable defined later in script?
by marto (Bishop) on Nov 12, 2012 at 15:56 UTC

    Wouldn't the simple (and sane) thing be to output the HTML after you have processed your input and given values to variables? Also, you may want to consider using HTML::Template or similar to separate your Perl code from your HTML/CSS/JS.

    You could also consider making this a dynamic page rather than writing a static HTML file each time the script runs. Though this may be out of scope for this coursework.


    I don't know if this is your entire code, but I'd suggest adding use strict; use warnings; (see Use strict and warnings or search for more), ensure you're opening files properly by checking for errors, for example:

    open (LOG, '<', 'IN-access.log') or die "cannot open < IN-access.log: +$!";

    Such things help prevent facepalm.

Re: Possible to refer to variable defined later in script?
by SuicideJunkie (Vicar) on Nov 12, 2012 at 15:53 UTC
    use ACME::TimeTravel::CPUfolding

    Or, you could rearrange the code to write to the file AFTER you figured out what to write.

Re: Possible to refer to variable defined later in script?
by Athanasius (Chancellor) on Nov 12, 2012 at 16:35 UTC

    It is possible to read the filehandle’s position immediately before printing the empty (zero) value, and then later to return to this position in the file and overtype the zero value with the correct one. But this requires the file to be opened for writing rather than appending:

    open(my $HTML, '>', 'OUT-access.html') or die "Cannot open file 'OUT-a +ccess.html' for writing: $!"; ... print $HTML "There were "; my $offset = tell $HTML; printf $HTML "%7d", 0; print $HTML " unique visitors in the logfile.<BR>\n"; ... # Calculate $IPcount; ... seek $HTML, $offset, 0; printf $HTML "%7d", $IPcount;

    (The value of “7” in the format "%7d" assumes that the count will have at most 7 digits. Choose whatever number is appropriate for your use-case.)

    See tell and seek.

    Athanasius <°(((><contra mundum

Re: Possible to refer to variable defined later in script?
by NetWallah (Canon) on Nov 12, 2012 at 22:55 UTC
    I have had a similar design issue in the past - at that time, what I did was to create an empty <DIV> element at the top, then populate it later in the page using perl-generated javascript code that referenced the DIV.

    update: Here is the Javascript function I called to update the DIV text:

    function replaceText(sId, sText) { var el; if (document.getElementById && (el = document.getElementById(sId))) { while (el.hasChildNodes()) el.removeChild(el.lastChild); el.appendChild(document.createTextNode(sText)); } }
    In my case, the ID belonged to a <td> element of a CGI generated table:
    td({-id=>'SPECIALNAME_' . $g->Identifier},'N/A'), # The 'N/A' gets r +eplaced

                 "By three methods we may learn wisdom: First, by reflection, which is noblest; Second, by imitation, which is easiest; and third by experience, which is the bitterest."           -Confucius

Re: Possible to refer to variable defined later in script?
by sundialsvc4 (Abbot) on Nov 13, 2012 at 01:07 UTC

    There are, IMHO, “a whole bunch of extremely good reasons why” it is best:   (a) to determine what you want to generate before you generate it; and (b) to use a templating tool to actually generate the HTML or anything-else.

    One of these reasons is “separation of concerns.”   If you do it “the other way,” the day will come when someone wants you to make some page-output change, e.g. so that the page looks noticeably-different in a particular case ... and, perhaps obviously (if you’re very lucky) but perhaps quite subtly, the answers start coming out wrong.   And the logic by that time is so danged jumbled-up that you wish you could rewrite it but in the meantime that you didn’t have to touch it.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1003468]
Approved by marto
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (2)
As of 2018-03-24 16:35 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (299 votes). Check out past polls.