Re: @ARGV while (<>) hangs
by toolic (Bishop) on Jan 08, 2008 at 18:30 UTC
|
sub delimit {
my ( $tos, $ccs, $rp, $sb, $body, $in_file ) = @_;
my @lines;
if ( defined $in_file ) { # file submited
@ARGV = $in_file;
$body = "";
while (<>) {
push( @lines, $_ ) unless (/espf\[/); # hangs here some
+times
} # end of while
} # end of if
} # end of sub
If you wrote the "delimit" sub, perhaps you could describe in words what you are trying to accomplish. It seems like you are trying to open a file named by the $in_file variable. Perhaps if you use the open function, instead of assigning to @ARGV (which is a little unusual), you could at least get some information as whether the input file exists. For example:
open my $fh, '<', $in_file or die "Error: can not open file $in_file $
+!";
| [reply] [d/l] [select] |
|
|
It's a really bad idea to modify globals (@ARGV and $_ in this case) without localizing them.
local @ARGV = ...;
local $_;
while (<>) {
...
}
| [reply] [d/l] [select] |
|
|
The delimit sub is designed to check and see if an infile is submitted and if it is remove any line from the $in_file that contains the characters espf[. The @ARGV while (<>) schema is because I got it from page 72 of my Learning Perl (4th addition) book.
| [reply] |
|
|
I think you are not well served by page 72 of Learning Perl.
It is far more clear, and much easier to debug, if you open the file directly, after checking, than in the background.
If you are feeling daring, then go with toolic's
open F, '<', $in_file or die "Can't open $in_file: $!";
followed by
while (<F>) {
push @lines, $_ unless /espf\[/
}
although if the goal is to edit $in_file deleting lines, then you probably don't want to push it into a temporary array, but instead open a temp file, write to the temp file, unlink $in_file, and rename the temp file to $in_file.
However, since this is probably doing a ton of disk access, I'd probably do a few sanity checks first.
return undef if not defined $in_file;
if (-e $in_file) {
if (-r $in_file) {
open F, "<", $in_file or die "Can't open $in_file: $!"
# etc
} else {
warn "can't read $in_file\n";
return undef;
}
} else {
warn "bad file $in_file submitted, but does not exist\n";
}
Part of the reason I say that reassigning ARGV is not good practice is the principle of least surprise. The "while (<>)" construct is best used in the fashion described in perlopentut:
One of the most common uses for open is one you never even notice. When you process the ARGV filehandle using <ARGV>, Perl actually does an implicit open on each file in @ARGV. Thus a program called like this:
$ myprogram file1 file2 file3
Can have all its files opened and processed one at a time using a construct no more complex than:
while (<>) {
# do something with $_
}
If @ARGV is empty when the loop first begins, Perl pretends you've opened up minus, that is, the standard input. In fact, $ARGV, the currently open file during <ARGV> processing, is even set to "-" in these circumstances.
While you *can* use the magic of an implicit open to open files, its better to avoid magic when possible for the next poor sap who has to debug your code.
--woody | [reply] [d/l] [select] |
Re: @ARGV while (<>) hangs
by cdarke (Prior) on Jan 08, 2008 at 20:23 UTC
|
If $in_file is undef then <> (which uses the ARGV filehandle) will read from standard-input (STDIN). I suspect that your script is not hanging, but trying to read from the keyboard. To prove this, when it hangs type a few characters, then <CTRL>+D assuming UNIX/Linux (<CTRL>+Z<RETURN> on Windows). If the program unblocks checkout the file name in $in_file - there probably isn't one. | [reply] |
|
|
The file is also intentionally executed w/o an $in_file that is to say one is not submitted. It never hangs in those instances because if(defined $in_file) keep @ARGV and the while(<>) from coming into the mix.
| [reply] |
|
|
That's not true. "-" is defined, yet will cause <> to read from STDIN. So would "cat |".
Along that same line, note that "rm -rf / |" would have "interesting" results. Why are you using <> (and thus the 2-arg open) instead of the safer 3-arg open?
| [reply] [d/l] [select] |
|
|
|
|
|
|
Re: @ARGV while (<>) hangs
by Errto (Vicar) on Jan 08, 2008 at 18:44 UTC
|
How do you know that it's hanging on the line you have marked? I'd suggest adding some debugging statements to make sure - just printing to a log file or standard error might help. | [reply] [d/l] |
|
|
I'm sorry but I do not haveany experience with debugging statements can you please tell me what sort of debugging statements I might add to accomplish this outcome.
| [reply] |
Re: @ARGV while (<>) hangs
by alexm (Chaplain) on Jan 08, 2008 at 19:25 UTC
|
It seems that the code is also incomplete, so we cannot try to reproduce your error. Could you please update your question with the full ./file_delimiter.pl script? If it's too large, at least the missing part that calls to delimit(...) would be fine.
BTW, don't forget to enclose the code with <code> ... </code> tags. | [reply] [d/l] [select] |
|
|
the file is very large and it exists on a private network (w/o internet access). However, here are the lines from the other scipt that call it.
require "./file_delimiter.pl";
&delimit($T, $C, $R, $S, $B, $filename);
| [reply] |
Re: @ARGV while (<>) hangs
by karavay (Beadle) on Jan 08, 2008 at 18:10 UTC
|
use code tags to display your code - it will make your thread much easier to mentally absorb :) | [reply] |