Newbie Looking for Advice/Comments on Script

D

dgp

I'm new to Perl, and would like any advice/input on the following
script. It is written to open a file provided by a command-line
argument, seach for "SECTION" header, grab the next 112 lines into an
array, then write out the array in a specific order. It seems to work,
but I'm looking for comments on how it might be improved. I'd
specifically like to do the following:
1) Remove leading and trailing whitespace from the lines that are
"pushed" onto @points. I can't seem to figure it out.
2) I borrowed the scalar<INF> for 1..112 from another topic in this
group. What is this doing? Is there a clearer way to grab the 112 lines
following the "SECTION" header?
3) I'd like check that a command line argument was provided, if not,
prompt the user for $infile.

#!C:\Perl\bin\perl.exe
# rpt2ibl.pl
# Generates ProE IBL File from BladeRunner RPT File
# Requires input filename as commandline argument.
# Example: rpt2ibl.pl inputfile.rpt

use warnings;

$infile = $ARGV[0]; #Get input filename from command line argument.
$outfile = $infile;
$outfile =~ s/\.[^.]+$/.ibl/; #Change output filename extension to ibl.


open (INF, "<$infile") or die "Cannot open $infile for read.\n$!\n";
open (OUTF, ">$outfile") or die "Cannot open $outfile for
write.\n$!\n";

print OUTF "Closed Index Pointwise\n\n"; #Write File Header

while (<INF>) { #Reads each line into $_
if ($_ =~ /SECTION\s\w-\w/) {
++$section; #Increment Section Number
@points=''; #Clear points array
push @points, scalar<INF> for 1..112; #Read points
print OUTF "Begin section ! $section\n"; #Write Section Header
print OUTF "\tBegin curve ! 1\n"; #Write curve header
print OUTF "@points[105..112]";
print OUTF "@points[1..9]";
print OUTF "\tBegin curve ! 2\n"; #Write curve header
print OUTF "@points[9..49]";
print OUTF "\tBegin curve ! 3\n"; #Write curve header
print OUTF "@points[49..65]";
print OUTF "\tBegin curve ! 4\n"; #Write curve header
print OUTF "@points[65..105]";
}
}

close INF;
close OUTF;

Thank you for any help you can provide.
Dave
 
P

Paul Lalli

I'm new to Perl

http://learn.perl.org is an excellent place to start
, and would like any advice/input on the following
script. It is written to open a file provided by a command-line
argument, seach for "SECTION" header, grab the next 112 lines into an
array, then write out the array in a specific order. It seems to work,
but I'm looking for comments on how it might be improved. I'd
specifically like to do the following:
1) Remove leading and trailing whitespace from the lines that are
"pushed" onto @points. I can't seem to figure it out.

Please check the Perl FAQ *before* posting:
perldoc -q space
"How do I strip blank space from the beginning/end of a string?"

2) I borrowed the scalar<INF> for 1..112 from another topic in this
group. What is this doing?

the actual line:
push @points, scalar<INF> for 1..112;
is syntactic sugar for:
for (1..112) {
push @points, scalar<INF>;
}
In a scalar context, <INF> will return the 'next' line from the opened
file. So you are adding the next line of the file to @points 112 times.
The 'scalar' is necessary because otherwise <INF> would be evaluated in
a list context, which would cause it to return ALL remaining lines in
the file.
Is there a clearer way to grab the 112 lines following the "SECTION"
header?

You could do a looping construct, taking note of the $. variable, which
holds the current input file line number, and break out of the loop when
$. is 112 more than it was when you found "SECTION".
3) I'd like check that a command line argument was provided, if not,
prompt the user for $infile.

Command line arguments are stored in @ARGV. If @ARGV is empty, there
were no arguments provided.
#!C:\Perl\bin\perl.exe
# rpt2ibl.pl
# Generates ProE IBL File from BladeRunner RPT File
# Requires input filename as commandline argument.
# Example: rpt2ibl.pl inputfile.rpt

use strict;
Always use strictures. They help prevent errors. After adding this
line, you will have to declare your variables with 'my'. This is a good
thing.
use warnings;
Good!!

$infile = $ARGV[0]; #Get input filename from command line argument.
$outfile = $infile;
$outfile =~ s/\.[^.]+$/.ibl/; #Change output filename extension to ibl.


open (INF, "<$infile") or die "Cannot open $infile for read.\n$!\n";
open (OUTF, ">$outfile") or die "Cannot open $outfile for
write.\n$!\n";

Most people prefer lexical filehandle references these days instead of
the all-caps barewords
open my $inf, '<', $infile or die "Cannot open $infile: $!";
(similar for OUTF)
print OUTF "Closed Index Pointwise\n\n"; #Write File Header

while (<INF>) { #Reads each line into $_
if ($_ =~ /SECTION\s\w-\w/) {

pattern matches default to $_. There is no reason to make it explicit.
(ie, remove "$_ =~ ")
++$section; #Increment Section Number

Your formatting is atrocious. I'm guessing this is due to the method
with which you have posted this to usenet. I'm also guessing you used
Google Groups to do so. Please don't. Google Groups has been
contacted - by many people - about their senseless stripping of
whitespace, and have thus far not responded. Until they do, use a real
newsreader.
@points=''; #Clear points array

This does not clear the @points array. This sets the @points array to
contain exactly one element, the empty string. To clear an array, do
@points = ();

However, this should be unnecessary, as you should be declaring @points
lexically at this stage. Change this line to
my @points;
and you will get a fresh copy of the lexical array @points for each
iteration of the loop.
push @points, scalar<INF> for 1..112; #Read points
print OUTF "Begin section ! $section\n"; #Write Section Header
print OUTF "\tBegin curve ! 1\n"; #Write curve header
print OUTF "@points[105..112]";

You are adding extra spaces in front of each line. You are doing this
because you've chosen to interpolate the array slice. Interpolated
arrays and slices are separated by the $" variable, which defaults to a
single space. To fix this, either locally set $" to the empty string:
local $" = '';

or, preferred, don't interpolate the slices. Just print them out:
print OUTF @points[105..112];
print OUTF "@points[1..9]";
print OUTF "\tBegin curve ! 2\n"; #Write curve header
print OUTF "@points[9..49]";
print OUTF "\tBegin curve ! 3\n"; #Write curve header
print OUTF "@points[49..65]";
print OUTF "\tBegin curve ! 4\n"; #Write curve header
print OUTF "@points[65..105]";
}
}

close INF;
close OUTF;

Thank you for any help you can provide.

Hope this is helpful to you.

Paul Lalli.

P.S. I will preemptively say this: If you choose to reply, please quote
what you are replying to. This newsgroup has seen a rash of Google
Groups posters who choose to reply without quoting anything. Only a
small fraction of the readers of this newsgroup use Google Groups to
read Usenet, for various and valid reasons. Thank you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top