File path components are separated with / on Unix, with \ on Windows, and with : on Macs. Some systems support neither hard links (link) nor symbolic links (symlink, readlink, lstat). Some systems pay attention to capitalization of filenames, some don't, and some pay attention when creating files but not when reading them.
There are modules that can help. The standard File::Spec modules provide some functions of the Right Thing persuasion:
That last line reads in ./temp/file.txt on Unix and Windows, or :temp:file.txt on Macs, or [.temp]file.txt on VMS, and stores the file's contents in $file.use File::Spec::Functions; chdir( updir() ); # go up one directory $file = catfile( curdir(), 'temp', 'file.txt' );
The File::Basename module, another platform-tolerant module bundled with Perl, splits a pathname into its components: the base filename, the full path to the directory, and the file suffix.
Here are some tips for writing portable file-manipulating Perl programs:
Don't use two files of the same name with different case, like test.pl and Test.pl, since some platforms ignore capitalization.
Constrain filenames to the 8.3 convention (eight-letter names and three-letter extensions) where possible. You can often get away with longer filenames as long as you make sure the filenames will remain unique when shoved through an 8.3-sized hole in the wall. (Hey, it's gotta be easier than shoving a camel through the eye of a needle.)
Minimize nonalphanumeric characters in filenames. Using underscores is often okay, but it wastes a character that could better be used for uniqueness on 8.3 systems. (Remember, that's why we don't usually put underscores into module names.)
Likewise, when using the AutoSplit module, try to constrain your subroutine names to eight characters or less, and don't give two subroutines the same name with different case. If you need longer subroutine names, make the first eight characters of each unique.
Always use < explicitly to open a file for reading; otherwise, on systems that allow punctuation in filenames, a file prefixed with a > character could result in a file being wiped out, and a file prefixed with a | character could result in a pipe open. That's because the two-argument form of open is magical and will interpret characters like >, <, and |, which may be the wrong thing to do. (Except when it's right.)
open(FILE, $existing_file) or die $!; # wrongish open(FILE, "<$existing_file") or die $!; # righter open(FILE, "<", $existing_file) or die $!; # righterer
Don't assume text files will end with a newline. They should, but sometimes people forget, especially when their text editor helps them forget.
Copyright © 2001 O'Reilly & Associates. All rights reserved.