Move prototype parsing related warnings from the 'syntax' top level warnings category...
[p5sagit/p5-mst-13.2.git] / pod / perlfaq5.pod
index 3e652bd..09da5bb 100644 (file)
@@ -196,7 +196,7 @@ example skips every fifth line:
                }
 
 If, for some odd reason, you really want to see the whole file at once
-rather than processing line by line, you can slurp it in (as long as
+rather than processing line-by-line, you can slurp it in (as long as
 you can fit the whole thing in memory!):
 
        open my $in,  '<',  $file      or die "Can't read old file: $!"
@@ -275,6 +275,52 @@ proper text file, so this may report one fewer line than you expect.
 
 This assumes no funny games with newline translations.
 
+=head2 How do I delete the last N lines from a file?
+X<lines> X<file>
+
+(contributed by brian d foy)
+
+The easiest conceptual solution is to count the lines in the 
+file then start at the beginning and print the number of lines
+(minus the last N) to a new file.
+
+Most often, the real question is how you can delete the last N
+lines without making more than one pass over the file, or how to 
+do it with a lot of copying. The easy concept is the hard reality when
+you might have millions of lines in your file.
+
+One trick is to use C<File::ReadBackwards>, which starts at the end of 
+the file. That module provides an object that wraps the real filehandle
+to make it easy for you to move around the file. Once you get to the 
+spot you need, you can get the actual filehandle and work with it as
+normal. In this case, you get the file position at the end of the last
+line you want to keep and truncate the file to that point:
+
+       use File::ReadBackwards;
+       
+       my $filename = 'test.txt';
+       my $Lines_to_truncate = 2;
+
+       my $bw = File::ReadBackwards->new( $filename ) 
+               or die "Could not read backwards in [$filename]: $!";
+       
+       my $lines_from_end = 0;
+       until( $bw->eof or $lines_from_end == $Lines_to_truncate ) 
+               {
+               print "Got: ", $bw->readline;
+               $lines_from_end++;
+               }
+       
+       truncate( $filename, $bw->tell );
+
+The C<File::ReadBackwards> module also has the advantage of setting
+the input record separator to a regular expression.
+
+You can also use the C<Tie::File> module which lets you access
+the lines through a tied array. You can use normal array operations
+to modify your file, including setting the last index and using 
+C<splice>.
+
 =head2 How can I use Perl's C<-i> option from within a program?
 X<-i> X<in-place>
 
@@ -725,10 +771,11 @@ one that doesn't use the shell to do globbing.
 =head2 Is there a leak/bug in glob()?
 X<glob>
 
-Due to the current implementation on some operating systems, when you
-use the glob() function or its angle-bracket alias in a scalar
-context, you may cause a memory leak and/or unpredictable behavior.  It's
-best therefore to use glob() only in list context.
+(contributed by brian d foy)
+
+Starting with Perl 5.6.0, C<glob> is implemented internally rather
+than relying on an external resource. As such, memory issues with 
+C<glob> aren't a problem in modern perls.
 
 =head2 How can I open a file with a leading ">" or trailing blanks?
 X<filename, special characters>
@@ -748,21 +795,19 @@ characters in the filename as special.
        open FILE, ">", ">file";     # filename is ">file"
 
 =head2 How can I reliably rename a file?
-X<rename> X<mv> X<move> X<file, rename> X<ren>
+X<rename> X<mv> X<move> X<file, rename>
 
 If your operating system supports a proper mv(1) utility or its
 functional equivalent, this works:
 
        rename($old, $new) or system("mv", $old, $new);
 
-It may be more portable to use the File::Copy module instead.
+It may be more portable to use the C<File::Copy> module instead.
 You just copy to the new file to the new name (checking return
 values), then delete the old one.  This isn't really the same
-semantically as a rename(), which preserves meta-information like
+semantically as a C<rename()>, which preserves meta-information like
 permissions, timestamps, inode info, etc.
 
-Newer versions of File::Copy export a move() function.
-
 =head2 How can I lock a file?
 X<lock> X<file, lock> X<flock>
 
@@ -914,17 +959,15 @@ Don't forget them or you'll be quite sorry.
 =head2 How do I get a file's timestamp in perl?
 X<timestamp> X<file, timestamp>
 
-If you want to retrieve the time at which the file was last
-read, written, or had its meta-data (owner, etc) changed,
-you use the B<-A>, B<-M>, or B<-C> file test operations as
-documented in L<perlfunc>.  These retrieve the age of the
-file (measured against the start-time of your program) in
-days as a floating point number. Some platforms may not have
-all of these times.  See L<perlport> for details. To
-retrieve the "raw" time in seconds since the epoch, you
-would call the stat function, then use localtime(),
-gmtime(), or POSIX::strftime() to convert this into
-human-readable form.
+If you want to retrieve the time at which the file was last read,
+written, or had its meta-data (owner, etc) changed, you use the B<-A>,
+B<-M>, or B<-C> file test operations as documented in L<perlfunc>.
+These retrieve the age of the file (measured against the start-time of
+your program) in days as a floating point number. Some platforms may
+not have all of these times.  See L<perlport> for details. To retrieve
+the "raw" time in seconds since the epoch, you would call the stat
+function, then use C<localtime()>, C<gmtime()>, or
+C<POSIX::strftime()> to convert this into human-readable form.
 
 Here's an example:
 
@@ -1125,7 +1168,7 @@ include also support for non-portable systems as well.
 The very first thing you should do is look into getting the Term::ReadKey
 extension from CPAN.  As we mentioned earlier, it now even has limited
 support for non-portable (read: not open systems, closed, proprietary,
-not POSIX, not Unix, etc) systems.
+not POSIX, not Unix, etc.) systems.
 
 You should also check out the Frequently Asked Questions list in
 comp.unix.* for things like this: the answer is essentially the same.