develooper Front page | perl.perl5.porters | Postings from July 2012

Re: [perl #113898] File::Spec::Unix->catfile("./a") ne File::Spec::Unix->catfile(".","a")

Thread Previous | Thread Next
From:
Vincent Pit
Date:
July 1, 2012 06:38
Subject:
Re: [perl #113898] File::Spec::Unix->catfile("./a") ne File::Spec::Unix->catfile(".","a")
Message ID:
4FF052CB.4020301@profvince.com
> I don't think this is a bug.  I think your second instance is a correct
> instance of the behavior set forth in the File::Spec documentation.
>
> "File::Spec::Unix::catfile:
>
> Concatenate one or more directory names and a filename to form a
> complete path ending with a filename"
>
> The documentation -- and this is true of File::Spec itself, as well --
> specifies that catfile() ought to take a non-zero list of directories
> and a filename.  Your second instance above does this.

I hadn't even realized that the documentation required at least one 
directory entry, given the case of "no directory" is handled explicitly 
both in catfile()'s implementation and tests. However, I'm pretty sure 
many people write catfile(@dirs, $file) without checking that @dirs is 
not empty. So, practically speaking, catfile() has to handle that case.

I can see several solutions :

- 1°) catfile() should always return canonical paths stripped from their 
leading ./ when they are relative. It means that catfile() would 
actually be reimplemented as canonpath(join '/', @_). This is 
consistent, but sometimes you need to prepend curdir() to a path in a 
portable way, like when you want pass an executable to system() (as in 
my original report).

- 2°) catfile() should always return canonical paths starting with ./ 
when they are relative. Theoretically, this is the best solution but I 
suspect it would break a lot of tests on CPAN that compare what 
catfile() returns against an hard-coded path.

- 3°) catfile() should just concatenate its arguments, without 
canonifying leadings "./". This is consistent (as far as catfile() is 
concerned), has limited breakage potential, and still allow to prepend a 
dot when needed, so it is my preferred way of fixing the issue.

To summarize, here's what catfile() returns for each of these strategies 
(0 being the current state of affairs) :

                     +-----+-----+-----+-----+
                     |  0  |  1  |  2  |  3  |
+-------------------+-----+-----+-----+-----+
|   catfile('a')    |  a  |  a  | ./a |  a  |
+-------------------+-----+-----+-----+-----+
|  catfile('./a')   |  a  |  a  | ./a | ./a |
+-------------------+-----+-----+-----+-----+
| catfile('.', 'a') | ./a |  a  | ./a | ./a |
+-------------------+-----+-----+-----+-----+

I have implemented solution 3°) in the topic branch 
vincent/normalize_unix_catfile in the repository, and I will smoke it 
against the CPAN when the machine is available.


Vincent




Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About