cvs commit: perlfaq perlfaq5.pod

[email protected] (Robert Spier) 23 Nov 2003 08:07:47 -0000
Newsgroups perl.cvs.perlfaq
Message-ID <[email protected]>
cvsuser     03/11/23 00:07:46

  Modified:    .        perlfaq5.pod
  Log:
  From: Iain Truskett <[email protected]>
  To: [email protected]
  Subject: Re: [PATCH perlfaq5] "How can I manipulate fixed-record-length files?"
  Date: Sun, 23 Nov 2003 01:30:13 +1100
  
  Get rid of symrefs, modernify, etc.
  
  Revision  Changes    Path
  1.30      +19 -16    perlfaq/perlfaq5.pod
  
  Index: perlfaq5.pod
  ===================================================================
  RCS file: /cvs/public/perlfaq/perlfaq5.pod,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -w -r1.29 -r1.30
  --- perlfaq5.pod	12 Aug 2003 02:44:46 -0000	1.29
  +++ perlfaq5.pod	23 Nov 2003 08:07:46 -0000	1.30
  @@ -1,6 +1,6 @@
   =head1 NAME
   
  -perlfaq5 - Files and Formats ($Revision: 1.29 $, $Date: 2003/08/12 02:44:46 $)
  +perlfaq5 - Files and Formats ($Revision: 1.30 $, $Date: 2003/11/23 08:07:46 $)
   
   =head1 DESCRIPTION
   
  @@ -153,8 +153,10 @@
   
   =head2 How can I manipulate fixed-record-length files?
   
  -The most efficient way is using pack() and unpack().  This is faster than
  -using substr() when taking many, many strings.  It is slower for just a few.
  +The most efficient way is using L<pack()|perlfunc/"pack"> and
  +L<unpack()|perlfunc/"unpack">.  This is faster than using
  +L<substr()|perlfunc/"substr"> when taking many, many strings.  It is
  +slower for just a few.
   
   Here is a sample chunk of code to break up and put back together again
   some fixed-format input lines, in this case from the output of a normal,
  @@ -162,22 +164,23 @@
   
       # sample input line:
       #   15158 p5  T      0:00 perl /home/tchrist/scripts/now-what
  -    $PS_T = 'A6 A4 A7 A5 A*';
  -    open(PS, "ps|");
  -    print scalar <PS>;
  -    while (<PS>) {
  -	($pid, $tt, $stat, $time, $command) = unpack($PS_T, $_);
  -	for $var (qw!pid tt stat time command!) {
  -	    print "$var: <$$var>\n";
  -	}
  -	print 'line=', pack($PS_T, $pid, $tt, $stat, $time, $command),
  -		"\n";
  -    }
  -
  -We've used C<$$var> in a way that forbidden by C<use strict 'refs'>.
  -That is, we've promoted a string to a scalar variable reference using
  -symbolic references.  This is okay in small programs, but doesn't scale
  -well.   It also only works on global variables, not lexicals.
  +    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 '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?