To test if something is a filehandle, use the fileno() function, like this:
if (defined(fileno($fh))) {
print "Filehandle!\n";
} else {
print "Not a filehandle\n";
}
fileno() works as you'd expect on both bare filehandles (eg, STDERR) and on references (eg, those returns from CGI::param and CGI::upload).
Trap for the unwary: Zero is a perfectly legal fileno, which is usually bound to STDIN. Hence you should always check to make sure that fileno returns a defined value, not just a true one. Otherwise you can get caught out if you're testing STDIN for filehandle-ness, or if your STDIN has been closed and something else has taken fileno 0 as its own.
Cheers,
Paul
| [reply] [d/l] |
But fileno fails to work on tied handles because there is no C-level filenumber associated with it. So unless you actually need to access the handle at the C level, I would recommend not causing gratuitous breakage with calls to fileno.
| [reply] |
I think the normal way to do this is by making the script die if the file that the filehandle is... er... attached to (I have no clue what the proper word is either, but I know what you mean) isn't there. So
open (FILEHANDLE, "$file") or die "couldn't open $file";
Certainly, that's what everyone tells me to do when I don't do it :)
§ George Sherston | [reply] [d/l] [select] |
His question asked how to verify that something you were just passed is really a filehandle and not, say, a string.
You are talking about how to open up a filehandle based on having the name of a file in a string.
Incidentally your snippet is not how you are supposed to do it. As it says in perlstyle, you need to include the output of $! in the error message. The information on what the OS thinks is wrong is often very important in debugging. Furthermore if you are accepting a filename from user input, and you do not trust the user (this is common in CGI scripts) then you do not want to open a file for reading that way. Instead you want to:
open(FILEHANDLE, "< $file") or die "Couldn't read '$file': $!";
The difference being that now you are only willing to read the file. So if they send you "filenames" which contain cute characters like "|", you won't gratify them by running arbitrary programs. (But you still need to worry about them naming files you don't want named. But that is a more complex issue by far.) | [reply] [d/l] |
I would wonder what problem you had with upload in an array context. I would try it with a current version, and then if that failed I would send a bug report.
But for CGI, at least in my version, you can put in a check with checking whether ref of the returned value is "Fh". That is, of course, highly dependent on the internals of CGI, and it may be a bad idea for that reason... | [reply] |
I think that the or die statement will do what you want, however if you would like the script to continue on if the file doesnt exist rather than exiting, you may want to try testing for the file using -e. Check out this, or just try
if (-e $filename) {
open(FH, $filename);
}
humbly -c | [reply] [d/l] [select] |