Opening files for reading and writing is all well and good when you know something about the files you're working with—for example, that they're all there, or that you're not about to overwrite something important. But sometimes in Perl you want to be able to check the properties of a file before you open it, or handle a file differently depending on the various properties of that file.
Perl has a (rather large) set of tests for the various properties of files: to see if they exist, that they have data in them, that they're a certain kind of file, or that it's a certain age. (1996 was a very good year for binary files, wasn't it?) These tests all look like switches (-e, -R, -o, and so on), but don't confuse them with actual switches (the reason they look like this is because they're borrowed from Unix shell scripting, and they look like that there).
Table 15.1 shows some of the more useful file tests. The perlfunc man page, in the entry for -X, contains the complete set (although you might note that not all the options are appropriate for all platforms).
Each of these tests can take a filename or a file handle as an argument; either will work (although if you're testing to see whether or not a file exists, you'll probably want to test the filename before calling open on it).
Each test returns either true (1) or false (""), except for –e, which returns undef if the file doesn't exist, -s, which returns the number of bytes (characters) in the file, and the time operators -M and -A, which return the number of seconds since the file was modified or accessed, respectively.
So, for example, let's say you wanted to modify the subject.pl script such that if the subjects.txt file exists, you'd prompt the user to make sure they want to overwrite it. Instead of the plain call to open we had, you could test to see if the file exists, and if it does, make sure the user wants to overwrite it. Study the following code:
if (-e 'subjects.txt') { print 'File exists. Overwrite (Y/N)? '; chomp ($_ = <STDIN>); while (/[^yn]/i) { print 'Y or N, please: '; chomp ($_ = <STDIN>); } if (/n/i) { die "subjects file already exists; exiting. "; } }
Here you see another use of the die function, this time away from the open function. If the user answers n to the overwrite question, you could simply exit the script; the die function is an explicit end and prints a message to that effect.