Re: how to prevent open from dying
by ikegami (Patriarch) on Jun 30, 2006 at 15:19 UTC
|
while (...) {
local *INFILE;
if (!open(INFILE, '<', $inputFile)) {
warn("Unable to open analysis file $inputFile: $!\n");
next; #
}
...
}
- Your error message was wrong. Don't assume it's because the file was not found. open sets $!, so use it. Also, it would be useful to specify the file for which the error occured.
- I used the 3-arg open for safety.
- Don't forget to limit the scope of your file handles (as done here using local).
| [reply] [d/l] [select] |
|
|
while ( ... ) {
open my $fh, '<', $inputFile or
warn( "Unable to open analysis file $inputFile: $!\n" );
next unless defined $fh
...
}
| [reply] [d/l] |
|
|
I hate testing for the same condition twice in a row, as you did.
while ( ... ) {
my $fh;
if (!open($fh, '<', $inputFile)) {
warn( "Unable to open analysis file $inputFile: $!\n" );
next;
}
...
}
| [reply] [d/l] |
|
|
| [reply] |
|
|
- yes, I'll use $! instead
- can you explain the "3arg" deal? So nothing can be slipped in the file name? Like "; cat /etc/passwd" or smth?
- what's the point of limiting file handles??
Anyway, thank you all for your replies.
| [reply] |
|
|
The open with 3 args seperate special characters from the filename, allowing you to access files you couldn't access before, and preventing the unintended creation, destruction and execution of other files.
Limiting the scope of all variables (not just file handles) is a great practice. It frees resources earlier. It limits the number of things the programmer and the maintainer must track. It prevents bugs and the maintainability nightmares of having a variable server multiple purposes. etc.
| [reply] [d/l] |
Re: how to prevent open from dying
by Zaxo (Archbishop) on Jun 30, 2006 at 15:20 UTC
|
open INFILE, '<', $inputFile or
warn("analysis file not found"), next;
| [reply] [d/l] |
|
|
I guess the only problem with this snipped is that it prints nothing to stdout. It just blows right through missing files and keeps going.
| [reply] |
|
|
| [reply] |
|
|
Re: how to prevent open from dying
by blue_cowdawg (Monsignor) on Jun 30, 2006 at 15:20 UTC
|
. I don't want it to die but print a msg instead and continue.
Try something like:
open(FILE,"< some_darn_file_or_another")
or do_something_else_besides_die();
|
}
sub do_something_else_besides_die {
printf "Belch!\n";
}
The call to die that you are referring to
is not mandatory. You can execute whatever code you want
after the or.
Now, the real issue is you need to do some sort of error
recovery upon a failed open such that you aren't trying to
read/write to an unopened file handle.
Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
| [reply] [d/l] [select] |
Re: how to prevent open from dying
by chromatic (Archbishop) on Jun 30, 2006 at 15:21 UTC
|
If you have the source code for this program, you could look for the Perl command that causes Perl to die and change it to the Perl command that causes Perl to print something.
I suspect I may be missing the point of your question though. Are you asking how to handle the exceptional condition? Then look at the documentation for eval. (From the command line, perldoc -f eval or perldoc -f die may help you. Otherwise, you can find perlfunc.pod online in many places.
| [reply] [d/l] [select] |
Re: how to prevent open from dying
by radiantmatrix (Parson) on Jun 30, 2006 at 18:58 UTC
|
I suspect that code is followed by one or more I/O operations on that file, and you certainly don't want to attempt those operations if the file isn't open. So, while you can simply replace die with warn or print (or any other statement), what you probably want to do is simple exception handling.
Something like this ought to do:
use strict; use warnings; #always a good idea!
#... some loop that sets $inputFile to the file path ...
eval {
# try to open the file, die and explain the problem on failure
open my $INFILE, '<', $inputFile or die "Cannot read '$inputFile':
+$!"
#.. do I/O on $INFILE (e.g. <$INFILE>, [doc://sysread], etc.) ..#
};
if ($@) {
# this catches the message from any "die" in the eval{} block
# the message will be in the scalar '$@';
print "!: Error while working on file-> $@"
}
#.. move on to the next file ..#
With this style of code, any operation inside the eval that causes a die (like an error while reading) will terminate only the eval block and set $@ to be the message from die. You can then handle this message appropriately and move on to the next file.
This is similar in spirit to Java's try{ } catch{} syntax.
| [reply] [d/l] [select] |
Re: how to prevent open from dying
by mikasue (Friar) on Jun 30, 2006 at 15:21 UTC
|
What do you want the message to say? Which file failed? | [reply] |