rz10@cornell.edu (Ray Zimmerman) writes: } Paul Schinder wrote: } >bob.dalgleish@sasknet.sk.ca (Bob Dalgleish) writes: } >} 2b) Replace File::basename.pl with an OO module that has constructors, and } >} parsers. } >} } >} Not knowing any better, I propose that the characters slash "/", backslash } >} "\", colon ":", left and right square bracket "[" and "]" be treated } >} specially for cross-platform purposes. } > } >No, I'm not sure I like this. What I would prefer under MacPerl is } >that anything that is legal on a Mac won't have to be encoded, which } >means, essentially, that any name without : and less than 32 characters } >in length is legal and should be accepted by a basename or } >basename-like routine. There should be no reserved characters other } >than those forbidden by the local OS. This is straightforward on Macs } >and Unix (and I assume on DOS). If you're doing cross platform work, } >you might want to teach it what's illegal on various platforms, and to } >tell it to encode characters illegal on that platform if the path would } >otherwise work but throw an error if it wouldn't, or something. But } >there shouldn't be any restrictions on the local character set or name } >length beside what already exist. } } But isn't the whole idea of basename to be able to do cross-platform stuff? } I'd think that if you're doing cross-platform work you'd want to have some } package that lets you do cross-platform file names without having to } "teach" it anything. In that case, it seems to me that Bob's suggestion to } treat all those characters as special is reasonable (can't think of any way } around it). If you want to be able to use any legal Mac file name, then } you're not writing cross-platform code and presumably wouldn't use the } basename (or whatever) package ... } } ... am I missing something? OK, it's clear it's time for a concrete example. I recently ported Net::FTP to MacPerl, and now have the same script running under MacPerl and Unix (I like to do this simply to prove it can be done) and with trivial changes it could be made to run under other OS's. In Net::FTP's put routine (it may not be called exactly that), Graham Barr (the module's author), in a routine which is given a pathname (full or partial), wants to find a file name to give to the remote machine. So what he does is essentially $file = $path; $file =~ s,.*/,,; You can imagine how well this works under MacPerl. So I replaced this with a if($Config::Config{'osname'} eq ...). But that's a stupid way to do this. I expect any author whose module is going into a general section (say Net:: ) of CPAN to attempt to write portable code. I do *not* expect him to know anything about Macintoshes or DOS/Windows or any other OS than the one he's writing on. So Graham Barr should be able to say (I never remember what basename is supposed to do, so let's give it a more descriptive name) $file = file_name($path); to find the file part of a local $path. *He* shouldn't need to know anything about file_name other than it returns the file name of a local $path. If he wants to test beforehand whether this filename is legal on a given operating system (say he's done ftp SYST and is able to know what OS the remote is running) if ($remote_sys) { unless(is_legal($file,$remote_sys)) { $file = legal_name($file,$remote_sys); } } or something like that. These routines, or something like them, should be defined in a module that ships with every version of Perl, they should always do the right thing for the local operating system, and they should know about as many OS's as is reasonable for cross-platform purposes. HOWEVER, something like file_name would be perfectly useful on my Mac, so I don't want $file = file_name("Macintosh HD:MacPerl:lib:[read]/[write].pl"); to give me any problems. It should return [read]/[write].pl, and not complain about the brackets or the /. If you look in libwww-perl-5b11, you'll find the authors are attempting to make the library platform portable. To do this, they have to write routines for various file systems to construct local paths (for file URL's). *They* shouldn't have to do this, this should be part of the standard Perl distribution. All they should do is make calls which are guaranteed to give a legal local path (or croak if it can't). Maybe the ultimate solution is to build into Perl itself the ability to both deal with the local convention and to recognize file URL's. So under MacPerl, the two statements open(FILE,"Macintosh HD:MacPerl:lib:Config.pm"); and open(FILE,"file:///Macintosh%20HD/MacPerl/lib/Config.pm") would do exactly the same thing. Since file URL's are already defined independent of any platform (yes, there's a strong whiff of Unix, but the encoding mechanism gives you ways of putting /'s in filenames or naming your files . or .. if you want), this may be the way to solve this particular problem. } } %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~% } | Ray Zimmerman (rz10@cornell.edu) | "The number you have | } | 428-B Phillips Hall | dialed is imaginary. | } | Cornell Univ., Ithaca, NY 14853 | Rotate phone 90 degrees | } | 607-255-9645 Fax: 607-254-4565 | and try again." | } %~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~% } } } --- -------- Paul J. Schinder NASA Goddard Space Flight Center, Code 693, Greenbelt, MD 20771 USA schinder@pjstoaster.pg.md.us