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?