cvs commit: perlfaq perlfaq1.pod perlfaq3.pod perlfaq4.pod perlfaq5.pod

[email protected] (brian d foy) 1 Feb 2006 01:37:21 -0000
Newsgroups perl.cvs.perlfaq
Message-ID <[email protected]>
cvsuser     06/01/31 17:37:21

  Modified:    .        perlfaq1.pod perlfaq3.pod perlfaq4.pod perlfaq5.pod
  Log:
  * perlfaq1: updated date we expect Perl 6 (I put 2008 just to be safe)
  
  * perlfaq3: How do I debug my Perl programs?
  	+ Rewrote to give it a friendly tone
  	+ Acctually answered the question
  	+ Added a paragraph about Devel::ebug
  	+ Added a list of commercial products
  
  + perlfaq4: How do I get a random number between X and Y?
  	+ Cleansed whitespace
  	+ Fixed up function name to describe what function does
  	+ Should we get rid of the prototype?
  
  + perlfaq5:  How can I make a filehandle local to a subroutine?  How do I pass filehandles between subroutines?  How do I make an array of filehandles?
  	+ lots and lots of whitespace fixes. The indention got all messed
  	up somewhere
  	+ answered the part of the question dealing with an array of
  	filehandles. that part had been skipped in earlier versions.
  
  Revision  Changes    Path
  1.20      +2 -2      perlfaq/perlfaq1.pod
  
  Index: perlfaq1.pod
  ===================================================================
  RCS file: /cvs/public/perlfaq/perlfaq1.pod,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- perlfaq1.pod	31 Dec 2005 00:54:37 -0000	1.19
  +++ perlfaq1.pod	1 Feb 2006 01:37:21 -0000	1.20
  @@ -111,7 +111,7 @@
   
   There is no perl6.x for the next couple of years.  Stay tuned,
   but don't worry that you'll have to change major versions of Perl
  -soon (i.e. before 2006).
  +soon (i.e. before 2008).
   
   =item *
   
  
  
  
  1.57      +35 -22    perlfaq/perlfaq3.pod
  
  Index: perlfaq3.pod
  ===================================================================
  RCS file: /cvs/public/perlfaq/perlfaq3.pod,v
  retrieving revision 1.56
  retrieving revision 1.57
  diff -u -r1.56 -r1.57
  --- perlfaq3.pod	31 Dec 2005 00:54:37 -0000	1.56
  +++ perlfaq3.pod	1 Feb 2006 01:37:21 -0000	1.57
  @@ -110,28 +110,41 @@
   
   =head2 How do I debug my Perl programs?
   
  -Have you tried C<use warnings> or used C<-w>?  They enable warnings
  -to detect dubious practices.
  +(contributed by brian d foy)
  +
  +Before you do anything else, you can help yourself by ensuring that
  +you let Perl tell you about problem areas in your code. By turning
  +on warnings and strictures, you can head off many problems before 
  +they get too big. You can find out more about these in L<strict>
  +and L<warnings>.
  +
  +	#!/usr/bin/perl
  +	use strict;
  +	use warnings;
  +	
  +Beyond that, the simplest debugger is the C<print> function. Use it
  +to look at values as you run your program:
  +
  +	print STDERR "The value is [$value]\n";
  +
  +The C<Data::Dumper> module can pretty-print Perl data structures:
  +
  +	use Data::Dumper( Dump );
  +	print STDERR "The hash is " . Dump( \%hash ) . "\n";
  +	
  +Perl comes with an interactive debugger, which you can start with the
  +C<-d> switch. It's fully explained in L<perldebug>.
  +
  +If you'd like a graphical user interface and you have Tk, you can use
  +C<ptkdb>. It's on CPAN and available for free.
  +
  +If you need something much more sophisicated and controllable, Leon
  +Brocard's Devel::ebug (which you can call with the -D switch as -Debug)
  +gives you the programmatic hooks into everything you need to write your
  +own (without too much pain and suffering).
   
  -Have you tried C<use strict>?  It prevents you from using symbolic
  -references, makes you predeclare any subroutines that you call as bare
  -words, and (probably most importantly) forces you to predeclare your
  -variables with C<my>, C<our>, or C<use vars>.
  -
  -Did you check the return values of each and every system call?  The operating
  -system (and thus Perl) tells you whether they worked, and if not
  -why.
  -
  -  open(FH, "> /etc/cantwrite")
  -    or die "Couldn't write to /etc/cantwrite: $!\n";
  -
  -Did you read L<perltrap>?  It's full of gotchas for old and new Perl
  -programmers and even has sections for those of you who are upgrading
  -from languages like I<awk> and I<C>.
  -
  -Have you tried the Perl debugger, described in L<perldebug>?  You can
  -step through your program and see what it's doing and thus work out
  -why what it's doing isn't what it should be doing.
  +You can also use a commercial debugger such as Affrus (Mac OS X), Komodo
  +from Activestate (Windows and Mac OS X), or EPIC (most platforms).
   
   =head2 How do I profile my Perl programs?
   
  
  
  
  1.74      +13 -10    perlfaq/perlfaq4.pod
  
  Index: perlfaq4.pod
  ===================================================================
  RCS file: /cvs/public/perlfaq/perlfaq4.pod,v
  retrieving revision 1.73
  retrieving revision 1.74
  diff -u -r1.73 -r1.74
  --- perlfaq4.pod	31 Dec 2005 00:54:37 -0000	1.73
  +++ perlfaq4.pod	1 Feb 2006 01:37:21 -0000	1.74
  @@ -362,6 +362,9 @@
   
   =head2 How do I get a random number between X and Y?
   
  +To get a random number between two values, you can use the
  +C<rand()> builtin to get a random number between 0 and
  +
   C<rand($x)> returns a number such that
   C<< 0 <= rand($x) < $x >>. Thus what you want to have perl
   figure out is a random number in the range from 0 to the
  @@ -371,19 +374,19 @@
   want a random number between 0 and 5 that you can then add
   to 10.
   
  -    my $number = 10 + int rand( 15-10+1 );
  +	my $number = 10 + int rand( 15-10+1 );
   
   Hence you derive the following simple function to abstract
   that. It selects a random integer between the two given
  -integers (inclusive), For example: C<random_int_in(50,120)>.
  +integers (inclusive), For example: C<random_int_between(50,120)>.
   
  -   sub random_int_in ($$) {
  -     my($min, $max) = @_;
  -      # Assumes that the two arguments are integers themselves!
  -     return $min if $min == $max;
  -     ($min, $max) = ($max, $min)  if  $min > $max;
  -     return $min + int rand(1 + $max - $min);
  -   }
  +	sub random_int_between ($$) {
  +		my($min, $max) = @_;
  +		# Assumes that the two arguments are integers themselves!
  +		return $min if $min == $max;
  +		($min, $max) = ($max, $min)  if  $min > $max;
  +		return $min + int rand(1 + $max - $min);
  +		}
   
   =head1 Data: Dates
   
  
  
  
  1.43      +265 -249  perlfaq/perlfaq5.pod
  
  Index: perlfaq5.pod
  ===================================================================
  RCS file: /cvs/public/perlfaq/perlfaq5.pod,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- perlfaq5.pod	31 Dec 2005 00:54:37 -0000	1.42
  +++ perlfaq5.pod	1 Feb 2006 01:37:21 -0000	1.43
  @@ -36,30 +36,30 @@
   Use select() to choose the desired handle, then set its
   per-filehandle variables.
   
  -    $old_fh = select(OUTPUT_HANDLE);
  -    $| = 1;
  -    select($old_fh);
  +	$old_fh = select(OUTPUT_HANDLE);
  +	$| = 1;
  +	select($old_fh);
   
   Some idioms can handle this in a single statement:
   
  -    select((select(OUTPUT_HANDLE), $| = 1)[0]);
  +	select((select(OUTPUT_HANDLE), $| = 1)[0]);
   
  -    $| = 1, select $_ for select OUTPUT_HANDLE;
  +	$| = 1, select $_ for select OUTPUT_HANDLE;
   
   Some modules offer object-oriented access to handles and their
   variables, although they may be overkill if this is the only
   thing you do with them.  You can use IO::Handle:
   
  -    use IO::Handle;
  -    open(DEV, ">/dev/printer");   # but is this?
  -    DEV->autoflush(1);
  +	use IO::Handle;
  +	open(DEV, ">/dev/printer");   # but is this?
  +	DEV->autoflush(1);
   
   or IO::Socket:
   
  -    use IO::Socket;		  # this one is kinda a pipe?
  +	use IO::Socket;		  # this one is kinda a pipe?
   	my $sock = IO::Socket::INET->new( 'www.example.com:80' );
   
  -    $sock->autoflush();
  +	$sock->autoflush();
   
   =head2 How do I change one line in a file/delete a line in a file/insert a line in the middle of a file/append to the beginning of a file?
   X<file, editing>
  @@ -75,12 +75,12 @@
   If your text file doesn't end with a newline, then it's not really a
   proper text file, so this may report one fewer line than you expect.
   
  -    $lines = 0;
  -    open(FILE, $filename) or die "Can't open `$filename': $!";
  -    while (sysread FILE, $buffer, 4096) {
  -	$lines += ($buffer =~ tr/\n//);
  -    }
  -    close FILE;
  +	$lines = 0;
  +	open(FILE, $filename) or die "Can't open `$filename': $!";
  +	while (sysread FILE, $buffer, 4096) {
  +		$lines += ($buffer =~ tr/\n//);
  +		}
  +	close FILE;
   
   This assumes no funny games with newline translations.
   
  @@ -92,19 +92,19 @@
   modifying the appropriate variables directly, you can get the same
   behavior within a larger program.  For example:
   
  -     # ...
  -     {
  -        local($^I, @ARGV) = ('.orig', glob("*.c"));
  -        while (<>) {
  -           if ($. == 1) {
  -               print "This line should appear at the top of each file\n";
  -           }
  -           s/\b(p)earl\b/${1}erl/i;        # Correct typos, preserving case
  -           print;
  -           close ARGV if eof;              # Reset $.
  -        }
  -     }
  -     # $^I and @ARGV return to their old values here
  +	# ...
  +	{
  +	local($^I, @ARGV) = ('.orig', glob("*.c"));
  +	while (<>) {
  +		if ($. == 1) {
  +			print "This line should appear at the top of each file\n";
  +		}
  +		s/\b(p)earl\b/${1}erl/i;        # Correct typos, preserving case
  +		print;
  +		close ARGV if eof;              # Reset $.
  +		}
  +	}
  +	# $^I and @ARGV return to their old values here
   
   This block modifies all the C<.c> files in the current directory,
   leaving a backup of the original data from each file in a new
  @@ -138,47 +138,50 @@
   
   Otherwise, you can use the File::Temp module.
   
  -  use File::Temp qw/ tempfile tempdir /;
  +	use File::Temp qw/ tempfile tempdir /;
   
  -  $dir = tempdir( CLEANUP => 1 );
  -  ($fh, $filename) = tempfile( DIR => $dir );
  +	$dir = tempdir( CLEANUP => 1 );
  +	($fh, $filename) = tempfile( DIR => $dir );
   
  -  # or if you don't need to know the filename
  +	# or if you don't need to know the filename
   
  -  $fh = tempfile( DIR => $dir );
  +	$fh = tempfile( DIR => $dir );
   
   The File::Temp has been a standard module since Perl 5.6.1.  If you
   don't have a modern enough Perl installed, use the C<new_tmpfile>
   class method from the IO::File module to get a filehandle opened for
   reading and writing.  Use it if you don't need to know the file's name:
   
  -    use IO::File;
  -    $fh = IO::File->new_tmpfile()
  +	use IO::File;
  +	$fh = IO::File->new_tmpfile()
   	or die "Unable to make new temporary file: $!";
   
   If you're committed to creating a temporary file by hand, use the
   process ID and/or the current time-value.  If you need to have many
   temporary files in one process, use a counter:
   
  -    BEGIN {
  +	BEGIN {
   	use Fcntl;
   	my $temp_dir = -d '/tmp' ? '/tmp' : $ENV{TMPDIR} || $ENV{TEMP};
   	my $base_name = sprintf("%s/%d-%d-0000", $temp_dir, $$, time());
  +
   	sub temp_file {
  -	    local *FH;
  -	    my $count = 0;
  -	    until (defined(fileno(FH)) || $count++ > 100) {
  +		local *FH;
  +		my $count = 0;
  +		until (defined(fileno(FH)) || $count++ > 100) {
   		$base_name =~ s/-(\d+)$/"-" . (1 + $1)/e;
   		# O_EXCL is required for security reasons.
   		sysopen(FH, $base_name, O_WRONLY|O_EXCL|O_CREAT);
  -	    }
  -	    if (defined(fileno(FH))
  +		}
  +
  +	if (defined(fileno(FH))
   		return (*FH, $base_name);
  -	    } else {
  +	    } 
  +	else {
   		return ();
   	    }
   	}
  -    }
  +	}
   
   =head2 How can I manipulate fixed-record-length files?
   X<fixed-length> X<file, fixed-length records>
  @@ -192,27 +195,27 @@
   some fixed-format input lines, in this case from the output of a normal,
   Berkeley-style ps:
   
  -    # sample input line:
  -    #   15158 p5  T      0:00 perl /home/tchrist/scripts/now-what
  -    my $PS_T = 'A6 A4 A7 A5 A*';
  -    open my $ps, '-|', 'ps';
  -    print scalar <$ps>;
  -    my @fields = qw( pid tt stat time command );
  -    while (<$ps>) {
  -        my %process;
  -        @process{@fields} = unpack($PS_T, $_);
  +	# sample input line:
  +	#   15158 p5  T      0:00 perl /home/tchrist/scripts/now-what
  +	my $PS_T = 'A6 A4 A7 A5 A*';
  +	open my $ps, '-|', 'ps';
  +	print scalar <$ps>;
  +	my @fields = qw( pid tt stat time command );
  +	while (<$ps>) {
  +		my %process;
  +		@process{@fields} = unpack($PS_T, $_);
   	for my $field ( @fields ) {
  -	    print "$field: <$process{$field}>\n";
  +		print "$field: <$process{$field}>\n";
   	}
   	print 'line=', pack($PS_T, @process{@fields} ), "\n";
  -    }
  +	}
   
   We've used a hash slice in order to easily handle the fields of each row.
   Storing the keys in an array means it's easy to operate on them as a
   group or loop over them with for. It also avoids polluting the program
   with global variables and using symbolic references.
   
  -=head2 How can I make a filehandle local to a subroutine?  How do I pass filehandles between subroutines?  How do I make an array of filehandles?
  +=head2 How can I make a filehandle local to a subroutine?  How do I pass filehandles between subroutines?  How do I make an array of filehandles? 
   X<filehandle, local> X<filehandle, passing> X<filehandle, reference>
   
   As of perl5.6, open() autovivifies file and directory handles
  @@ -228,6 +231,19 @@
   
   	process_file( $fh );
   
  +If you like, you can store these filehandles in an array or a hash.
  +If you access them directly, they aren't simple scalars and you
  +need to give C<print> a little help by placing the filehandle 
  +reference in braces. Perl can only figure it out on its own when
  +the filehandle reference is a simple scalar.
  +
  +	my @fhs = ( $fh1, $fh2, $fh3 );
  +	
  +	for( $i = 0; $i <= $#fhs; $i++ ) {
  +		print {$fhs[$i]} "just another Perl answer, \n";
  +		}
  +
  +
   Before perl5.6, you had to deal with various typeglob idioms
   which you may see in older code.
   
  @@ -248,18 +264,18 @@
   in a place that a filehandle is expected.  Here are ways
   to get indirect filehandles:
   
  -    $fh =   SOME_FH;       # bareword is strict-subs hostile
  -    $fh =  "SOME_FH";      # strict-refs hostile; same package only
  -    $fh =  *SOME_FH;       # typeglob
  -    $fh = \*SOME_FH;       # ref to typeglob (bless-able)
  -    $fh =  *SOME_FH{IO};   # blessed IO::Handle from *SOME_FH typeglob
  +	$fh =   SOME_FH;       # bareword is strict-subs hostile
  +	$fh =  "SOME_FH";      # strict-refs hostile; same package only
  +	$fh =  *SOME_FH;       # typeglob
  +	$fh = \*SOME_FH;       # ref to typeglob (bless-able)
  +	$fh =  *SOME_FH{IO};   # blessed IO::Handle from *SOME_FH typeglob
   
   Or, you can use the C<new> method from one of the IO::* modules to
   create an anonymous filehandle, store that in a scalar variable,
   and use it as though it were a normal filehandle.
   
  -    use IO::Handle;                     # 5.004 or higher
  -    $fh = IO::Handle->new();
  +	use IO::Handle;                     # 5.004 or higher
  +	$fh = IO::Handle->new();
   
   Then use any of those as you would a normal filehandle.  Anywhere that
   Perl is expecting a filehandle, an indirect filehandle may be used
  @@ -268,32 +284,32 @@
   the C<< <FH> >> diamond operator will accept either a named filehandle
   or a scalar variable containing one:
   
  -    ($ifh, $ofh, $efh) = (*STDIN, *STDOUT, *STDERR);
  -    print $ofh "Type it: ";
  -    $got = <$ifh>
  -    print $efh "What was that: $got";
  +	($ifh, $ofh, $efh) = (*STDIN, *STDOUT, *STDERR);
  +	print $ofh "Type it: ";
  +	$got = <$ifh>
  +	print $efh "What was that: $got";
   
   If you're passing a filehandle to a function, you can write
   the function in two ways:
   
  -    sub accept_fh {
  -        my $fh = shift;
  -        print $fh "Sending to indirect filehandle\n";
  -    }
  +	sub accept_fh {
  +		my $fh = shift;
  +		print $fh "Sending to indirect filehandle\n";
  +	}
   
   Or it can localize a typeglob and use the filehandle directly:
   
  -    sub accept_fh {
  -        local *FH = shift;
  -        print  FH "Sending to localized filehandle\n";
  -    }
  +	sub accept_fh {
  +		local *FH = shift;
  +		print  FH "Sending to localized filehandle\n";
  +	}
   
   Both styles work with either objects or typeglobs of real filehandles.
   (They might also work with strings under some circumstances, but this
   is risky.)
   
  -    accept_fh(*STDOUT);
  -    accept_fh($handle);
  +	accept_fh(*STDOUT);
  +	accept_fh($handle);
   
   In the examples above, we assigned the filehandle to a scalar variable
   before using it.  That is because only simple scalar variables, not
  @@ -302,24 +318,24 @@
   something other than a simple scalar variable as a filehandle is
   illegal and won't even compile:
   
  -    @fd = (*STDIN, *STDOUT, *STDERR);
  -    print $fd[1] "Type it: ";                           # WRONG
  -    $got = <$fd[0]>                                     # WRONG
  -    print $fd[2] "What was that: $got";                 # WRONG
  +	@fd = (*STDIN, *STDOUT, *STDERR);
  +	print $fd[1] "Type it: ";                           # WRONG
  +	$got = <$fd[0]>                                     # WRONG
  +	print $fd[2] "What was that: $got";                 # WRONG
   
   With C<print> and C<printf>, you get around this by using a block and
   an expression where you would place the filehandle:
   
  -    print  { $fd[1] } "funny stuff\n";
  -    printf { $fd[1] } "Pity the poor %x.\n", 3_735_928_559;
  -    # Pity the poor deadbeef.
  +	print  { $fd[1] } "funny stuff\n";
  +	printf { $fd[1] } "Pity the poor %x.\n", 3_735_928_559;
  +	# Pity the poor deadbeef.
   
   That block is a proper block like any other, so you can put more
   complicated code there.  This sends the message out to one of two places:
   
  -    $ok = -x "/bin/cat";
  -    print { $ok ? $fd[1] : $fd[2] } "cat stat $ok\n";
  -    print { $fd[ 1+ ($ok || 0) ]  } "cat stat $ok\n";
  +	$ok = -x "/bin/cat";
  +	print { $ok ? $fd[1] : $fd[2] } "cat stat $ok\n";
  +	print { $fd[ 1+ ($ok || 0) ]  } "cat stat $ok\n";
   
   This approach of treating C<print> and C<printf> like object methods
   calls doesn't work for the diamond operator.  That's because it's a
  @@ -330,7 +346,7 @@
   would work, but only because readline() requires a typeglob.  It doesn't
   work with objects or strings, which might be a bug we haven't fixed yet.
   
  -    $got = readline($fd[0]);
  +	$got = readline($fd[0]);
   
   Let it be noted that the flakiness of indirect filehandles is not
   related to whether they're strings, typeglobs, objects, or anything else.
  @@ -361,28 +377,28 @@
   This subroutine will add commas to your number:
   
   	sub commify {
  -	   local $_  = shift;
  -	   1 while s/^([-+]?\d+)(\d{3})/$1,$2/;
  -	   return $_;
  -	   }
  +		local $_  = shift;
  +		1 while s/^([-+]?\d+)(\d{3})/$1,$2/;
  +		return $_;
  +		}
   
   This regex from Benjamin Goldberg will add commas to numbers:
   
  -   s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1,/g;
  +	s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1,/g;
   
   It is easier to see with comments:
   
  -   s/(
  -       ^[-+]?            # beginning of number.
  -       \d+?              # first digits before first comma
  -       (?=               # followed by, (but not included in the match) :
  -          (?>(?:\d{3})+) # some positive multiple of three digits.
  -          (?!\d)         # an *exact* multiple, not x * 3 + 1 or whatever.
  -       )
  -      |                  # or:
  -       \G\d{3}           # after the last group, get three digits
  -       (?=\d)            # but they have to have more digits after them.
  -   )/$1,/xg;
  +	s/(
  +		^[-+]?             # beginning of number.
  +		\d+?               # first digits before first comma
  +		(?=                # followed by, (but not included in the match) :
  +			(?>(?:\d{3})+) # some positive multiple of three digits.
  +			(?!\d)         # an *exact* multiple, not x * 3 + 1 or whatever.
  +		)
  +		|                  # or:
  +		\G\d{3}            # after the last group, get three digits
  +		(?=\d)             # but they have to have more digits after them.
  +	)/$1,/xg;
   
   =head2 How can I translate tildes (~) in a filename?
   X<tilde> X<tilde expansion>
  @@ -413,12 +429,12 @@
   Because you're using something like this, which truncates the file and
   I<then> gives you read-write access:
   
  -    open(FH, "+> /path/name");		# WRONG (almost always)
  +	open(FH, "+> /path/name");		# WRONG (almost always)
   
   Whoops.  You should instead use this, which will fail if the file
   doesn't exist.
   
  -    open(FH, "+< /path/name");  	# open for update
  +	open(FH, "+< /path/name");  	# open for update
   
   Using ">" always clobbers or creates.  Using "<" never does
   either.  The "+" doesn't change this.
  @@ -426,52 +442,52 @@
   Here are examples of many kinds of file opens.  Those using sysopen()
   all assume
   
  -    use Fcntl;
  +	use Fcntl;
   
   To open file for reading:
   
  -    open(FH, "< $path")                                 || die $!;
  -    sysopen(FH, $path, O_RDONLY)                        || die $!;
  +	open(FH, "< $path")                                 || die $!;
  +	sysopen(FH, $path, O_RDONLY)                        || die $!;
   
   To open file for writing, create new file if needed or else truncate old file:
   
  -    open(FH, "> $path") || die $!;
  -    sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT)        || die $!;
  -    sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT, 0666)  || die $!;
  +	open(FH, "> $path") || die $!;
  +	sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT)        || die $!;
  +	sysopen(FH, $path, O_WRONLY|O_TRUNC|O_CREAT, 0666)  || die $!;
   
   To open file for writing, create new file, file must not exist:
   
  -    sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT)         || die $!;
  -    sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT, 0666)   || die $!;
  +	sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT)         || die $!;
  +	sysopen(FH, $path, O_WRONLY|O_EXCL|O_CREAT, 0666)   || die $!;
   
   To open file for appending, create if necessary:
   
  -    open(FH, ">> $path") || die $!;
  -    sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT)       || die $!;
  -    sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT, 0666) || die $!;
  +	open(FH, ">> $path") || die $!;
  +	sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT)       || die $!;
  +	sysopen(FH, $path, O_WRONLY|O_APPEND|O_CREAT, 0666) || die $!;
   
   To open file for appending, file must exist:
   
  -    sysopen(FH, $path, O_WRONLY|O_APPEND)               || die $!;
  +	sysopen(FH, $path, O_WRONLY|O_APPEND)               || die $!;
   
   To open file for update, file must exist:
   
  -    open(FH, "+< $path")                                || die $!;
  -    sysopen(FH, $path, O_RDWR)                          || die $!;
  +	open(FH, "+< $path")                                || die $!;
  +	sysopen(FH, $path, O_RDWR)                          || die $!;
   
   To open file for update, create file if necessary:
   
  -    sysopen(FH, $path, O_RDWR|O_CREAT)                  || die $!;
  -    sysopen(FH, $path, O_RDWR|O_CREAT, 0666)            || die $!;
  +	sysopen(FH, $path, O_RDWR|O_CREAT)                  || die $!;
  +	sysopen(FH, $path, O_RDWR|O_CREAT, 0666)            || die $!;
   
   To open file for update, file must not exist:
   
  -    sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT)           || die $!;
  -    sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT, 0666)     || die $!;
  +	sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT)           || die $!;
  +	sysopen(FH, $path, O_RDWR|O_EXCL|O_CREAT, 0666)     || die $!;
   
   To open a file without blocking, creating if necessary:
   
  -    sysopen(FH, "/foo/somefile", O_WRONLY|O_NDELAY|O_CREAT)
  +	sysopen(FH, "/foo/somefile", O_WRONLY|O_NDELAY|O_CREAT)
   	    or die "can't open /foo/somefile: $!":
   
   Be warned that neither creation nor deletion of files is guaranteed to
  @@ -526,7 +542,7 @@
   If your operating system supports a proper mv(1) utility or its
   functional equivalent, this works:
   
  -    rename($old, $new) or system("mv", $old, $new);
  +	rename($old, $new) or system("mv", $old, $new);
   
   It may be more portable to use the File::Copy module instead.
   You just copy to the new file to the new name (checking return
  @@ -589,14 +605,14 @@
   
   A common bit of code B<NOT TO USE> is this:
   
  -    sleep(3) while -e "file.lock";	# PLEASE DO NOT USE
  -    open(LCK, "> file.lock");		# THIS BROKEN CODE
  +	sleep(3) while -e "file.lock";	# PLEASE DO NOT USE
  +	open(LCK, "> file.lock");		# THIS BROKEN CODE
   
   This is a classic race condition: you take two steps to do something
   which must be done in one.  That's why computer hardware provides an
   atomic test-and-set instruction.   In theory, this "ought" to work:
   
  -    sysopen(FH, "file.lock", O_WRONLY|O_EXCL|O_CREAT)
  +	sysopen(FH, "file.lock", O_WRONLY|O_EXCL|O_CREAT)
   		or die "can't open  file.lock: $!";
   
   except that lamentably, file creation (and deletion) is not atomic
  @@ -614,18 +630,18 @@
   
   Anyway, this is what you can do if you can't help yourself.
   
  -    use Fcntl qw(:DEFAULT :flock);
  -    sysopen(FH, "numfile", O_RDWR|O_CREAT) 	 or die "can't open numfile: $!";
  -    flock(FH, LOCK_EX) 				 or die "can't flock numfile: $!";
  -    $num = <FH> || 0;
  -    seek(FH, 0, 0) 				 or die "can't rewind numfile: $!";
  -    truncate(FH, 0) 				 or die "can't truncate numfile: $!";
  -    (print FH $num+1, "\n")			 or die "can't write numfile: $!";
  -    close FH 					 or die "can't close numfile: $!";
  +	use Fcntl qw(:DEFAULT :flock);
  +	sysopen(FH, "numfile", O_RDWR|O_CREAT) 	 or die "can't open numfile: $!";
  +	flock(FH, LOCK_EX) 				 or die "can't flock numfile: $!";
  +	$num = <FH> || 0;
  +	seek(FH, 0, 0) 				 or die "can't rewind numfile: $!";
  +	truncate(FH, 0) 				 or die "can't truncate numfile: $!";
  +	(print FH $num+1, "\n")			 or die "can't write numfile: $!";
  +	close FH 					 or die "can't close numfile: $!";
   
   Here's a much better web-page hit counter:
   
  -    $hits = int( (time() - 850_000_000) / rand(1_000) );
  +	$hits = int( (time() - 850_000_000) / rand(1_000) );
   
   If the count doesn't impress your friends, then the code might.  :-)
   
  @@ -664,20 +680,20 @@
   If you're just trying to patch a binary, in many cases something as
   simple as this works:
   
  -    perl -i -pe 's{window manager}{window mangler}g' /usr/bin/emacs
  +	perl -i -pe 's{window manager}{window mangler}g' /usr/bin/emacs
   
   However, if you have fixed sized records, then you might do something more
   like this:
   
  -    $RECSIZE = 220; # size of record, in bytes
  -    $recno   = 37;  # which record to update
  -    open(FH, "+<somewhere") || die "can't update somewhere: $!";
  -    seek(FH, $recno * $RECSIZE, 0);
  -    read(FH, $record, $RECSIZE) == $RECSIZE || die "can't read record $recno: $!";
  -    # munge the record
  -    seek(FH, -$RECSIZE, 1);
  -    print FH $record;
  -    close FH;
  +	$RECSIZE = 220; # size of record, in bytes
  +	$recno   = 37;  # which record to update
  +	open(FH, "+<somewhere") || die "can't update somewhere: $!";
  +	seek(FH, $recno * $RECSIZE, 0);
  +	read(FH, $record, $RECSIZE) == $RECSIZE || die "can't read record $recno: $!";
  +	# munge the record
  +	seek(FH, -$RECSIZE, 1);
  +	print FH $record;
  +	close FH;
   
   Locking and error checking are left as an exercise for the reader.
   Don't forget them or you'll be quite sorry.
  @@ -699,18 +715,18 @@
   
   Here's an example:
   
  -    $write_secs = (stat($file))[9];
  -    printf "file %s updated at %s\n", $file,
  +	$write_secs = (stat($file))[9];
  +	printf "file %s updated at %s\n", $file,
   	scalar localtime($write_secs);
   
   If you prefer something more legible, use the File::stat module
   (part of the standard distribution in version 5.004 and later):
   
  -    # error checking left as an exercise for reader.
  -    use File::stat;
  -    use Time::localtime;
  -    $date_string = ctime(stat($file)->mtime);
  -    print "file $file updated at $date_string\n";
  +	# error checking left as an exercise for reader.
  +	use File::stat;
  +	use Time::localtime;
  +	$date_string = ctime(stat($file)->mtime);
  +	print "file $file updated at $date_string\n";
   
   The POSIX::strftime() approach has the benefit of being,
   in theory, independent of the current locale.  See L<perllocale>
  @@ -724,12 +740,12 @@
   read and write times from its first argument to all the rest
   of them.
   
  -    if (@ARGV < 2) {
  -	die "usage: cptimes timestamp_file other_files ...\n";
  -    }
  -    $timestamp = shift;
  -    ($atime, $mtime) = (stat($timestamp))[8,9];
  -    utime $atime, $mtime, @ARGV;
  +	if (@ARGV < 2) {
  +		die "usage: cptimes timestamp_file other_files ...\n";
  +		}
  +	$timestamp = shift;
  +	($atime, $mtime) = (stat($timestamp))[8,9];
  +	utime $atime, $mtime, @ARGV;
   
   Error checking is, as usual, left as an exercise for the reader.
   
  @@ -751,7 +767,7 @@
   If you only have to do this once, you can print individually
   to each filehandle.
   
  -    for $fh (FH1, FH2, FH3) { print $fh "whatever\n" }
  +	for $fh (FH1, FH2, FH3) { print $fh "whatever\n" }
   
   =head2 How can I read in an entire file all at once?
   X<slurp> X<file, slurping>
  @@ -761,24 +777,24 @@
   	use File::Slurp;
   
   	$all_of_it = read_file($filename); # entire file in scalar
  -    @all_lines = read_file($filename); # one line perl element
  +	@all_lines = read_file($filename); # one line perl element
   
   The customary Perl approach for processing all the lines in a file is to
   do so one line at a time:
   
  -    open (INPUT, $file) 	|| die "can't open $file: $!";
  -    while (<INPUT>) {
  -	chomp;
  -	# do something with $_
  -    }
  -    close(INPUT)	    	|| die "can't close $file: $!";
  +	open (INPUT, $file) 	|| die "can't open $file: $!";
  +	while (<INPUT>) {
  +		chomp;
  +		# do something with $_
  +		}
  +	close(INPUT)	    	|| die "can't close $file: $!";
   
   This is tremendously more efficient than reading the entire file into
   memory as an array of lines and then processing it one element at a time,
   which is often--if not almost always--the wrong approach.  Whenever
   you see someone do this:
   
  -    @lines = <INPUT>;
  +	@lines = <INPUT>;
   
   you should think long and hard about why you need everything loaded at
   once.  It's just not a scalable solution.  You might also find it more
  @@ -789,16 +805,16 @@
   
   You can read the entire filehandle contents into a scalar.
   
  -    {
  +	{
   	local(*INPUT, $/);
   	open (INPUT, $file) 	|| die "can't open $file: $!";
   	$var = <INPUT>;
  -    }
  +	}
   
   That temporarily undefs your record separator, and will automatically
   close the file at block exit.  If the file is already open, just use this:
   
  -    $var = do { local $/; <INPUT> };
  +	$var = do { local $/; <INPUT> };
   
   For ordinary files you can also use the read function.
   
  @@ -830,18 +846,18 @@
   interface (POSIX), you can use the following code, which you'll note
   turns off echo processing as well.
   
  -    #!/usr/bin/perl -w
  -    use strict;
  -    $| = 1;
  -    for (1..4) {
  -	my $got;
  -	print "gimme: ";
  -	$got = getone();
  -	print "--> $got\n";
  -    }
  +	#!/usr/bin/perl -w
  +	use strict;
  +	$| = 1;
  +	for (1..4) {
  +		my $got;
  +		print "gimme: ";
  +		$got = getone();
  +		print "--> $got\n";
  +		}
       exit;
   
  -    BEGIN {
  +	BEGIN {
   	use POSIX qw(:termios_h);
   
   	my ($term, $oterm, $echo, $noecho, $fd_stdin);
  @@ -856,40 +872,40 @@
   	$noecho   = $oterm & ~$echo;
   
   	sub cbreak {
  -	    $term->setlflag($noecho);
  -	    $term->setcc(VTIME, 1);
  -	    $term->setattr($fd_stdin, TCSANOW);
  -	}
  -
  +		$term->setlflag($noecho);
  +		$term->setcc(VTIME, 1);
  +		$term->setattr($fd_stdin, TCSANOW);
  +		}
  +	
   	sub cooked {
  -	    $term->setlflag($oterm);
  -	    $term->setcc(VTIME, 0);
  -	    $term->setattr($fd_stdin, TCSANOW);
  -	}
  +		$term->setlflag($oterm);
  +		$term->setcc(VTIME, 0);
  +		$term->setattr($fd_stdin, TCSANOW);
  +		}
   
   	sub getone {
  -	    my $key = '';
  -	    cbreak();
  -	    sysread(STDIN, $key, 1);
  -	    cooked();
  -	    return $key;
  -	}
  +		my $key = '';
  +		cbreak();
  +		sysread(STDIN, $key, 1);
  +		cooked();
  +		return $key;
  +		}
   
  -    }
  +	}
   
  -    END { cooked() }
  +	END { cooked() }
   
   The Term::ReadKey module from CPAN may be easier to use.  Recent versions
   include also support for non-portable systems as well.
   
  -    use Term::ReadKey;
  -    open(TTY, "</dev/tty");
  -    print "Gimme a char: ";
  -    ReadMode "raw";
  -    $key = ReadKey 0, *TTY;
  -    ReadMode "normal";
  -    printf "\nYou said %s, char number %03d\n",
  -        $key, ord $key;
  +	use Term::ReadKey;
  +	open(TTY, "</dev/tty");
  +	print "Gimme a char: ";
  +	ReadMode "raw";
  +	$key = ReadKey 0, *TTY;
  +	ReadMode "normal";
  +	printf "\nYou said %s, char number %03d\n",
  +		$key, ord $key;
   
   =head2 How can I tell whether there's a character waiting on a filehandle?
   
  @@ -903,11 +919,11 @@
   It's very system dependent.  Here's one solution that works on BSD
   systems:
   
  -    sub key_ready {
  -	my($rin, $nfd);
  -	vec($rin, fileno(STDIN), 1) = 1;
  -	return $nfd = select($rin,undef,undef,0);
  -    }
  +	sub key_ready {
  +		my($rin, $nfd);
  +		vec($rin, fileno(STDIN), 1) = 1;
  +		return $nfd = select($rin,undef,undef,0);
  +		}
   
   If you want to find out how many characters are waiting, there's
   also the FIONREAD ioctl call to be looked at.  The I<h2ph> tool that
  @@ -915,37 +931,37 @@
   can be C<require>d.  FIONREAD ends up defined as a function in the
   I<sys/ioctl.ph> file:
   
  -    require 'sys/ioctl.ph';
  +	require 'sys/ioctl.ph';
   
  -    $size = pack("L", 0);
  -    ioctl(FH, FIONREAD(), $size)    or die "Couldn't call ioctl: $!\n";
  -    $size = unpack("L", $size);
  +	$size = pack("L", 0);
  +	ioctl(FH, FIONREAD(), $size)    or die "Couldn't call ioctl: $!\n";
  +	$size = unpack("L", $size);
   
   If I<h2ph> wasn't installed or doesn't work for you, you can
   I<grep> the include files by hand:
   
  -    % grep FIONREAD /usr/include/*/*
  -    /usr/include/asm/ioctls.h:#define FIONREAD      0x541B
  +	% grep FIONREAD /usr/include/*/*
  +	/usr/include/asm/ioctls.h:#define FIONREAD      0x541B
   
   Or write a small C program using the editor of champions:
   
  -    % cat > fionread.c
  -    #include <sys/ioctl.h>
  -    main() {
  -        printf("%#08x\n", FIONREAD);
  -    }
  -    ^D
  -    % cc -o fionread fionread.c
  -    % ./fionread
  -    0x4004667f
  +	% cat > fionread.c
  +	#include <sys/ioctl.h>
  +	main() {
  +	    printf("%#08x\n", FIONREAD);
  +	}
  +	^D
  +	% cc -o fionread fionread.c
  +	% ./fionread
  +	0x4004667f
   
   And then hard code it, leaving porting as an exercise to your successor.
   
  -    $FIONREAD = 0x4004667f;         # XXX: opsys dependent
  +	$FIONREAD = 0x4004667f;         # XXX: opsys dependent
   
  -    $size = pack("L", 0);
  -    ioctl(FH, $FIONREAD, $size)     or die "Couldn't call ioctl: $!\n";
  -    $size = unpack("L", $size);
  +	$size = pack("L", 0);
  +	ioctl(FH, $FIONREAD, $size)     or die "Couldn't call ioctl: $!\n";
  +	$size = unpack("L", $size);
   
   FIONREAD requires a filehandle connected to a stream, meaning that sockets,
   pipes, and tty devices work, but I<not> files.
  @@ -955,7 +971,7 @@
   
   First try
   
  -    seek(GWFILE, 0, 1);
  +	seek(GWFILE, 0, 1);
   
   The statement C<seek(GWFILE, 0, 1)> doesn't change the current position,
   but it does clear the end-of-file condition on the handle, so that the
  @@ -985,8 +1001,8 @@
   If you check L<perlfunc/open>, you'll see that several of the ways
   to call open() should do the trick.  For example:
   
  -    open(LOG, ">>/foo/logfile");
  -    open(STDERR, ">&LOG");
  +	open(LOG, ">>/foo/logfile");
  +	open(STDERR, ">&LOG");
   
   Or even with a literal numeric descriptor:
   
  @@ -1008,17 +1024,17 @@
   numeric descriptor as with MHCONTEXT above.  But if you really have
   to, you may be able to do this:
   
  -    require 'sys/syscall.ph';
  -    $rc = syscall(&SYS_close, $fd + 0);  # must force numeric
  -    die "can't sysclose $fd: $!" unless $rc == -1;
  +	require 'sys/syscall.ph';
  +	$rc = syscall(&SYS_close, $fd + 0);  # must force numeric
  +	die "can't sysclose $fd: $!" unless $rc == -1;
   
   Or, just use the fdopen(3S) feature of open():
   
  -    {
  +	{
   	local *F;
   	open F, "<&=$fd" or die "Cannot reopen fd=$fd: $!";
   	close F;
  -    }
  +	}
   
   =head2 Why can't I use "C:\temp\foo" in DOS paths?  Why doesn't `C:\temp\foo.exe` work?
   X<filename, DOS issues>
  @@ -1065,8 +1081,8 @@
   
   Here's an algorithm from the Camel Book:
   
  -    srand;
  -    rand($.) < 1 && ($line = $_) while <>;
  +	srand;
  +	rand($.) < 1 && ($line = $_) while <>;
   
   This has a significant advantage in space over reading the whole file
   in.  You can find a proof of this method in I<The Art of Computer
  @@ -1085,24 +1101,24 @@
   
   Saying
   
  -    print "@lines\n";
  +	print "@lines\n";
   
   joins together the elements of C<@lines> with a space between them.
   If C<@lines> were C<("little", "fluffy", "clouds")> then the above
   statement would print
   
  -    little fluffy clouds
  +	little fluffy clouds
   
   but if each element of C<@lines> was a line of text, ending a newline
   character C<("little\n", "fluffy\n", "clouds\n")> then it would print:
   
  -    little
  -     fluffy
  -     clouds
  +	little
  +	 fluffy
  +	 clouds
   
   If your array contains lines, just print them:
   
  -    print @lines;
  +	print @lines;
   
   =head1 AUTHOR AND COPYRIGHT