Re: [MacPerl-Porters] Re: File::Spec catfile etc.
[email protected] (Peter Prymmer)
| Newsgroups | perl.perl5.porters,perl.macperl.porters,perl.vmsperl |
|---|---|
| Message-ID | <[email protected]> |
On Sat, 15 Sep 2001, Barrie Slaymaker wrote:
> On Sat, Sep 15, 2001 at 05:46:11PM -0700, Peter Prymmer wrote:
> >
> > I think that I understood the intent of the proposed distinction to be
> > made between C<File::Spec->catfile();> and
> > C<File::Spec::${Platform}->catfile();> calls.
>
> Yup. The assumption being that if you're dialing up a specific
> File::Spec::Foo, then you know what you're doing, and best of luck to
> you.
Yes I understood your intent with that aspect of the proposal.
> > Should perl have warned in that case?
>
> All File::Spec::* platforms but Unix happen to use the : as a token in
> their grammar, so the non-portable path warning would come through on
> any platform that didn't happen to use File::Spec::Unix. Unix should not
> warn, since it thinks you want a directory named "C:" in the final path
> (which would be relative to the cwd, in that case, a further oddness).
OK so you are propsing that anything matching =~ m/:/ would be warned
about.
> > Let's consider another example:
> >
> > $ create/directory DKA200:[FOO]
> > $ create DKA200:[FOO]BAR.
> > Hello from BAr
> > ^Z
> > $ define/translation=concealed C DKA200
> > $ perl "-MFile::Spec" -e "print File::Spec->catfile('C:','foo','bar')"
> >
> > Should perl have warned in this latter case? If so why?
>
> Yes, you're passing a volume name to catfile() via the generic
> File::Spec interface. s/catfile/catpath/ and you'd be Ok.
>
> Hmmm, new meme: a DCL shell on cygwin. What "fun" ;-).
Don't laugh there are at least two software companies that make DCL on NT
emulators. One is called xcelr8 (or somesuch) and the other is VCL.
> > The point I was trying to make was that absolute specs, as opposed to
> > relative specs, can be intrinsically "unportable".
>
> Even relative specs can be distinclty non-portable. This spec on a
> DOSish machine:
>
> "....\\foo"
>
> is like
>
> "../../../foo"
>
> (on Unix or DOS). And things like what ( updir, updir, "foo" ) paths do
> on different OSs when the cwd (or simulated cwd) is in or just below
> root are another way relative paths are non-portable.
Sure (but why issue warnings?).
> > The need to warn may be moot since the person using them probably
> > already knows that they're committing a non-portable act by using an
> > absolute spec.
>
> Why use File::Spec to glue together non-portable paths? It's a lot less
> convenient than basic string manipulation, and the weasel clause I added
I think here we disagree. The punctuation characters that one might warn
about can be perl regular expression meta characters. For example the
unix forward slash '/' needs often to be expressed as '\/' in a non \Q reg
exp context. The most commonly used path separator character on VMS
native specs is the period, but VMS also sets off the directory portion of
its paths with either matched sqare brackets:
DAYG$DKA200:[DIR.SUBDIR.SUBSUBDIR]FILE.EXT;3
or with angle brackets (typically used in locales where the [ and ]
characters are not easily input from the keyboard, but valid everywhere)
DAYG$DKA200:<DIR.SUBDIR.SUBSUBDIR>FILE.EXT.3
(and yes the period for the version can be used instead of the
semi-colon). Another twist with VMS specs is that within a directory a
subdirectory has a file type that has to be ignored upon concatenation.
For example the sub sub directory that contains FILE.EXT version three in
the above example is known as:
DAYG$DKA200:[DIR.SUBDIR]SUBSUBDIR.DIR;1
Stripping off the s/\.DIR\;1// is easier carried out by a well tested
library call (that is smart enough to chop off .DIR.1/i e.g.).
Hence I might have a tricky path concatenation platform such as VMS where
I want a lib to deal with all the corner cases and edge case and I would
like for my program to simply be able to catenate() and splitpath() via
library calls. If I wanted to port that to NT at some future date it
would entail relatively few changes.
> (don't warn if the call File::Spec::Foo->bar() instead of via
> File::Spec->bar()) means that if you are writing platform-specific code,
> then you should use the right File::Spec for that platform to dodge the
> warnings.
>
> The DCL trick you showed is nice, how likely is that in "the real world"
> when running a script that is ostensibly portable (because it uses
> File::Spec in the first place)?
You seem to have pre-supposed that any use of File::Spec has to have a
goal of portability from which you conclude that portability warnings will
cause no harm. I think that the assumption that the use of File::Spec is
only done with the goal of portability in mind needs to be re-examined.
> > Admittedly I used tricks outside of perl to make one look a
> > bit like the other, but can we stuff all such tricks into
> > File/Spec/Win32.pm and File/Spec/VMS.pm?
>
> Don't want to stuff any tricks in there, just emit some helpful (I hope)
> warnings to let you know you're using cat{dir,file} instead of
> catpath().
They will break previously working programs. They will render warnings in
the example already pointed out by Bart Lateur, namely:
use Cwd;
$fullpath = File::Spec->catfile(cwd, "bar" ) ;
Bart and I think that ought not warn on any platform where File::Spec.pm
and Cwd work. It ought also be portable.
One would also obtain warnings with constructs such as:
$fullpath = File::Spec->catfile('','usr','local/bin','perl');
which would need to be changed to
$fullpath = File::Spec::Unix->catfile('','usr','local/bin','perl');
in your proposal despite the fact that '/usr/local/bin/perl' is a
perfectly valid file spec on NT, W2k, and VMS.
Allow me to offer yet another argument the reductio ad absurdum. Clearly
the following ought to warn if portability warnings were added:
$fullpath = File::Spec->catfile('','usr','local','bin','perl');
Why is that? Obviously that path will never be portable to a DOS derived
OS where volumes do not have three letter names like USR: but instead have
single letter names like A: and C: hence the warnings ought to warn:
Warning: a volume of USR:\\local\\bin\\perl is not allowed on DOS.
Thus Perl's File::Spec module will dictate a new unix file system layout:
instead of traditional top directory names like /usr or /bin or the
sysVish /opt one would need to only mkdir things like /a (for
/dev/floppy?), /b /c /d etc. We would have to petition the Unix kernel
and application programmers to do away with programs that deal with
unportable /dev or /var or /etc directories.
There would also have to be path component length checks. I seem to
recall that a portion of either the ANSI or ISO C standard mentions that 6
characters should be considered the maximum (that is less that the 8 from
8.3). Consider the names of the longer ANSI headers which follow 6.1:
e.g. stdlib.h limits.h etc. Hence File::Spec ought to warn if any path
component exceeds 6 characters. VMS' RMS ODS-2 supports only 8 levels of
directory concatenation from a give MFD (tricks can be played with rooted
logical names to extend the 8 to 16) hence there should be a limit and
somthing like:
$fullpath = File::Spec ->
catfile('','H','two','three','four','five','six','seven','eight','nine');
ought to warn with "Too many arguments to catfile()".
But basically I think all of the above are ridiculous. Why should I see
any VMS related warnings if I am using perl's File::Spec for scripts that
will run only on Unix and NT? Why should I rename all of my top level
directories on Unix if I never intend to have my scripts run on anything
except Unix and MacOS? etc.
> > But then we move File::Spec from being flexible and capable of handling
> > both portable and platform specific concatenation issues to one in which
> > the warnings now dictate which arguments we are allowed to pass in.
>
> Hmmm? You can still do all of the things you want to do, the warnings
> just nudge you towards declaring your script's platform-specific nature
> by using the appropriate File::Spec::Foo, or be (at least partially)
> portable using the right method for the job (catpath()).
>
> > My concern is that such a change would actually detract from the
> > current ease of use of File::Spec.
>
> Understood & appreciated. Either we should make File::Spec for
> cross-platform or platform-specific code (the former being it's raison
> d'etre, however rough a start it had, the latter being a potential that
> I see in it and occasionally use), or we should leave File::Spec alone
> with the underspecified API and uneven implementation it currently
> provides. I prefer the former, but pragmatism may indicate the latter.
>
> > was your intent to warn under cygwin with a leading M{\/\/[A-Z]\/}i ?
> > What about UNC path names?
>
> Not too concerned about covering every single base, but UNC and drive
> letters on Win32 seem like low hanging fruit. Passing a "/" in to
> File::Spec::Unix->cat{file,dir}() (presumably what gets used on the OS X
> and AIX platforms which you mentioned) would be a warning. That latter
> one is the most likely to cause the most warnings, I'd guess that a lot
> of code lets directory separators sneak in to cat{file,dir} calls.
A lot does and if the module does not warn then old programs do not break.
> > I see what you want to achieve and laud the goal. I think that
> > encouraging _any_ use of File::Spec may be a better way to come closer to
> > attaining the portability goal,
>
> I think this is where we differ, encouraging File::Spec to be used
> non-portably is not a way to get to portable File::Spec uses. In fact,
> my biggest reservation about introducing warnings at this late date is
> that I suspect there are a noticable number of non-portable uses of
> File::Spec out there sleeping peacefully under the porch and I don't
> want to wake them all up (see the original messages, IIRC, this meme
> hasn't carried through to the last few messages). That's the pragmatic
> bit that could trump the warnings suggestion.
I think that there may be a compromise way around both my concern and
yours. How about adding one or more new tag name(s) to the export list of
File::Spec such that if I had a script like:
use File::Spec qw(:PPC);
I could then turn on the warnings for "Portable Path Checks" (or whatever
else you might want to call it). If they get too onerous then I change it
back to:
use File::Spec;
and the warnings go away. In other words the new warnings are not on by
default but must be requested explicitly by the masochists.
One could imagine an embellishment with a collection of separate tags such
as:
Use File::Spec qw(:VMS):
to turn on the VMS related warnings but without changing the calls from:
File::Spec->method()
into:
File::Spec::VMS->method()
Does this sound reasonable?
Peter Prymmer