From simon.urbanek at r-project.org  Wed Mar 28 00:31:49 2007
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Tue, 27 Mar 2007 18:31:49 -0400
Subject: [Rd] Limitation of dirname() and basename()
In-Reply-To: <46098FDC.4010707@fhcrc.org>
References: <460807A7.5030405@aon.at>	<Pine.LNX.4.64.0703270744580.9277@gannet.stats.ox.ac.uk>	<46095818.9080703@aon.at>
	<46096180.5070907@cimr.cam.ac.uk>	<46096739.20006@aon.at>
	<ADFA2A8A-B14B-44D9-899C-EFBE529E6F66@r-project.org>
	<46098FDC.4010707@fhcrc.org>
Message-ID: <0060E2BA-CABF-40C3-8C1A-19D9B5384835@r-project.org>


On Mar 27, 2007, at 5:42 PM, Herve Pages wrote:

> Simon Urbanek wrote:
>> Your proposed behavior is inconsistent, anyway. The purpose of  
>> dirname is to return parent directory of the entity represented by  
>> the pathname.
>
> Mmmm, I don't think this is true:
>
>> dirname("aaa/..")
>   [1] "aaa"
>
> "aaa" is not the parent directory of "aaa/.."
>
> Same here:
>
>> dirname("/usr/./.")
>   [1] "/usr/."
>

Yes, the problem is that most dirname implementations don't  
canonicalize the path - they are working on the string representation  
and don't use the underlying FS. I wasn't saying that dirname is  
perfect, in fact I refrained from commenting on this earlier exactly  
because of the behavior you describe, but the decision to remove  
trailing slashes was a deliberate as can be seen from the specs.  
Semantically correct behavior (taking the definition of the dirname  
function literally) would be dirname "/usr/." = "/", basename "/ 
usr/." = "usr". However, I suspect that not many people would expect  
this ;). As was proposed earlier, one could think of "true" dirname"  
or perhaps better "parentdir" function, although admittedly I don't  
see an issue here ...

Cheers,
Simon



>
>> "/my/path" and "/my/path/" are equivalent as they both
>> represent the directory "path" whose parent is "/my", therefore
>> returning "/my/path" in either case is inconsistent with the purpose
>> of this function. As of trailing slashes (independently of dirname),
>> sadly, some programs exploit the equivalence of both representations
>> by encoding meta-information in the representation, but this behavior
>> is quite confusing and error-prone. You're free to add such special
>> cases to your application, but there is no reason to add such
>> confusion to R.
>
> Note that Python's designers were not afraid to emancipate from  
> Unix for
> this particular case:
>
>>>> import os.path
>>>> os.path.dirname("aaa/..")
>   'aaa'
>>>> os.path.dirname("aaa/../")
>   'aaa/..'
>
>
> Also note that, if the goal was to mimic Unix behaviour, then why not
> fully go for it, even for edge-cases:
>
>   R
>   ----
>> dirname("/")
>   [1] "/"
>> basename("/")
>   [1] ""
>
>   Unix
>   ----
>   hpages at lamb1:~> dirname "/"
>   /
>   hpages at lamb1:~> basename "/"
>   /
>
> Just my 2 cents...
>
> Cheers,
> H.
>
>
>>
>> Cheers,
>> Simon
>>
>>
>>
>>>>> Prof Brian Ripley wrote:
>>>>>> These functions work as they should: did you not read the help  
>>>>>> page
>>>>>> which explicitly tells you what happens in this case?
>>>>>>
>>>>>> The Unix originals work in the same way:
>>>>>>
>>>>>> gannet% dirname /my/path/
>>>>>> /my
>>>>>>
>>>>>> Please DO study the R posting guide and do the homework  
>>>>>> requesting
>>>>>> of you before posting.
>>>>>>
>>>>>> On Mon, 26 Mar 2007, cstrato wrote:
>>>>>>
>>>>>>> Dear all,
>>>>>>>
>>>>>>> I have already twice encountered a case which I consider a
>>>>>>> limitation of
>>>>>>> dirname() and basename().
>>>>>>>
>>>>>>> In my functions I have a parameter "outfile" which e.g. tells
>>>>>>> where
>>>>>>> a file
>>>>>>> should be stored. Usually "outfile" is of the form:
>>>>>>> oufile = "/my/path/myname.txt"
>>>>>>>
>>>>>>>> outfile <- "/my/path/myname.txt"
>>>>>>>> dirname(outfile)
>>>>>>> [1] "/my/path"
>>>>>>>> basename(outfile)
>>>>>>> [1] "myname.txt"
>>>>>>>
>>>>>>> However, in addition I want to be able to define the path only,
>>>>>>> while
>>>>>>> creating the name "myname.txt" automatically.
>>>>>>> Sorrowly, I get the following:
>>>>>>>
>>>>>>>> outfile <- "/my/path/"
>>>>>>>> dirname(outfile)
>>>>>>> [1] "/my"
>>>>>>>> basename(outfile)
>>>>>>> [1] "path"
>>>>>>>
>>>>>>> It would be great if dirname() and basename() could recognize:
>>>>>>> dirname("/my/path/")      = /my/path/
>>>>>>> basename(""/my/path/")  = ""
>>>>>>> i.e. they should be able to recognize a trailing "/".
>>>>>> Not according to the documentation.
>>>>>>
>>>>>>> Best regards
>>>>>>> Christian
>>>>>>> _._._._._._._._._._._._._._._._
>>>>>>> C.h.i.s.t.i.a.n S.t.r.a.t.o.w.a
>>>>>>> V.i.e.n.n.a       A.u.s.t.r.i.a
>>>>>>> _._._._._._._._._._._._._._._._
>>>>> ______________________________________________
>>>>> R-devel at r-project.org mailing list
>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>
>>>>
>>> ______________________________________________
>>> R-devel at r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>
>>>
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>



[Rd] Limitation of dirname() and basename()
Simon Urbanek