Using Tie::File is going to be cleaner and more robust than my home-rolled implementation. But I'll show you a home-grown alternative anyway.

And if your book is telling you that 'cat' is the best solution to prepending something to a file from a CGI script, I'd have to disagree with the book and question its value. "cat" is not as portable, and I just don't like relying on system commands when there is a more Perlish solution.

As for how to do what I first described, here's one way:

use strict; use warnings; my $tempfile = "temp.txt"; my $origfile = "guestbook.txt"; my $prepend_text = "Stuff to prepend...\n"; open TEMP, ">$tempfile" or die "Can't create temp file. $!\n"; print TEMP $prepend_text; open ORIG, "<$origfile" or die "Can't read guestbook file. $!\n"; while ( my $line = <ORIG> ) { print TEMP $line; } close ORIG; close TEMP or die "Unable to close output file: $!\n"; rename $tempfile, $origfile;

But don't just cut-n-paste that snippet, because it doesn't even begin to address important issues like file locking, which is something you really have to be concerned with, particularly when writing to files from a CGI script.

Also, it doesn't deal with how to generate a temporary file that doesn't already exist, and it doesn't address the portability of the rename function. You might find it necessary, depending on your OS, to use File::Copy and unlink with my method. ...and File::Temp.

I recommend that you take a look at perlfaq5 and perlopentut as additional reading materials. Writing to files from a CGI script (or any environment where more than one entity might be trying to write to a file at the same time) is a little tricky, and you will save yourself a lot of headaches by understanding the various issues at hand. perlfaq5 includes discussions on file locking, prepending, and creating temporary filenames.

Update: Now here's an example of using the Tie::File module that everyone keeps talking about:

use strict; use warnings; use Tie::File; my $string = "Text to be prepended.\n"; my @array; { my $obj = tie @array, 'Tie::File', "guestbook.txt" or die "Can't open the guestbook file. $!\n"; $obj->flock; unshift @array, $string; untie @array; }

That's it! And the good news is that this example also locks the file so that if two people submit your guestbook form at the same time you won't get a garbled file. As you can see, Tie::File handles a lot of the details for you. You might notice the use of $obj within an enclosing lexical block. The importance isn't immediately obvious, but remember that at the end of the lexical block, $obj falls out of scope, which happens to be the way that Tie::File's documentation suggests you use to unlock the file after closing it with untie.

Update: If it's likely that your guestbook is going to grow to a pretty good size, and you can't live with the inefficiency of a flat-file growing large, it becomes time to look into database solutions which do scale well, and do make it quite easy to prepend, append, inpend, and unpend (excuse the linguistic liberties) data. Chances are though, that unless you're set to become the next eBay or Amazon, (or perlmonks.org) your guestbook is going to remain small enough that flatfiles are just fine.


Dave


"If I had my life to do over again, I'd be a plumber." -- Albert Einstein

In reply to Re: Re: Re: simple message board by davido
in thread simple message board by chrisrowe

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.