Search code examples
perlpathabsolute-path

Perl directory concatenation


Is there a function say f (in base Perl or a library) such that:

f("/a/b/c", "./d") == "/a/b/c/d"
f("/a/b/c", "../d") == "/a/b/d"
f("/a/b/c", "/d") == "/d"

Basically, it returns the directory that would result from repeatedly cding.


Solution

  • Core's File::Spec has such a function (rel2abs), but I prefer Path::Class (because it's too easy to use File::Spec incorrectly).

    use Path::Class qw( dir );
    say dir('./d')->absolute('/a/b/c');    # /a/b/c/d
    say dir('../d')->absolute('/a/b/c');   # /a/b/d
    say dir('/d')->absolute('/a/b/c');     # /d
    

    Use file instead of dir if you're create a path to a file.

    By the way, ./d is just a wordy way of writing d.


    Oops, on unix systems, that returns /a/b/c/../d for the middle one because it's impossible to know /a/b/c/../d means /a/b/d without checking the file system. (It could actually be /a/b/e/f/d.) Off the top of my head, I don't know any tool that makes absolute paths by checking the file system using a base other than the pwd.