http://www.perlmonks.org?node_id=703403

Roots, dirs and files. An instance script might set
$web_root C:/www $domain_root domain
A config file might have
docroot docroot art_root articles pic_root pics
A base class could have helper methods/assessors for each of the “roots”
Sub docroot{ my $self = shift; my $cnf = $self->cnf; return join( q{/}, $cnf->param(q{$web_root}), $cnf->param(q{$domain_root}), $cnf->param(q{docroot}), ); } sub art_root { my $self = shift; my $cnf = $self->cnf; return join( q{/}, $self->docroot, $cnf->param(q{art_root} ); }
A dir, is a xxx_root, and possibly one or more dir names. A file is a dir with a file name on the end.
my $article_file = join( q{/}, $self->art_root, $art_dirname, $art_filename, );
Anything that needs to be in an html page is $href and $src etc.

What’s wrong with path? Take a selection of core modules:

File::Basename - Parse file paths into directory, filename and suffix.
File::Path - create or remove directory trees
File::Spec - portably perform operations on file names

I find it confusing to keep on top of what a path is in the different contexts. Throw base and suffix into the mix and I’m rereading the docs again for the umpteenth time. File::Spec’s abs2rel talks about $base and $path. And where did those trees come from? And what do you do with a suffix list?

I would use these modules more if I didn’t get into such a tangle. I invariably have helper methods with names that better fit the conventions I’ve outlined e.g. mkdir.

While far from perfect everything has been a lot smoother since banning path.

A plague on paths!

How do monks manage to avoid such confusion?

update: fixed the join syntax
update2: fixed the links

Replies are listed 'Best First'.
Re: File system nomenclature. Death to path!
by ikegami (Patriarch) on Aug 10, 2008 at 13:17 UTC

    Where do relative paths fit into your schema? I find I need to distinguish between fully qualified paths and simply qualified paths.

    I also find no reason to have to different nomenclature for directory paths and file paths.

    I use
    fnFile name (no path)
    qnQualified file name (rel or abs path)
    fqnFully qualified file name (abs path)
    fhFile handle
    fhdhDirectory handle

    For example,

    my $log_fn = 'log'; my $log_qn = catfile($log_dir_qn, $log_fn); my $log_fqn = rel2abs($log_qn); open(my $log_fh, '<', $log_qn); my $log_dir_fn = 'log'; my $log_dir_qn = catdir($app_dir_qn, $log_fn); my $log_dir_fqn = rel2abs($log_dir_qn); opendir(my $log_dir_dh, $log_dir_qn);

    Update: Fixed copy and paste error where "fh" appeared where "dh" should have been.

Re: File system nomenclature. Death to path!
by dragonchild (Archbishop) on Aug 11, 2008 at 02:26 UTC
    I don't use any of the modules listed. I use Path::Class and be done with it. If I have to deal with hrefs, I use URI and be done with it. They even work together! If there's anything I need to know, it's in the POD for those two modules or there's someone I know who knows it.

    In other words, unless it's something you have to know on a day-to-day basis, leave it be and know where to find the documentation. Do you really know all the different argument lists for splice()? What about vec()? I don't, but I know that http://perldoc.perl.org does. Good nuff.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: File system nomenclature. Death to path!
by hangon (Deacon) on Aug 10, 2008 at 13:32 UTC

    Actually path doesn't bother me at all. It either points to a file or a directory, and I find it no more ambiguous than some other aspects of programming. We all have our peeves, and for me it's C style for loops. Every time I encounter one of these I feel like I need a bath. On the other hand, if you could get everyone to agree on a standard file system nomenclature I'll happily go along with it.

      First step is admitting you have a problem :)
Re: File system nomenclature. Death to path!
by graff (Chancellor) on Aug 10, 2008 at 22:52 UTC
    If you're complaining about always having to go back to the man pages for the standard modules that you use every other week because you can't memorize them (as opposed to the things you use every day, and are therefor memorized), my vote is: get over it, get used to it, and do whatever works for you.

    Before I learned Perl, I lived and breathed C, but every time I had to use read() or fread(), write() or fwrite(), or any of the str* functions, I had to go back to the man page, because I couldn't keep them straight. These days, I'm still going back to "perldoc perlre" more often than I'd like, in order to get the right syntax for positive/negative look-ahead/behind.

    As for the "vagueness" of the term "path", it makes perfect sense in a unix/linux world, where directories are just a type of file, and a path is just a way to get to a file (whatever type it may be). As ikegami points out above, a path can be relative (to one's current position in the file system) or absolute. It can also be fairly twisty, with one or more "../" components scattered within it.

    I have no problem with using more careful/specific terminology in appropriate settings, as demonstrated in your config examples, but I also have no problem with the current use of "path", even in the modules you mentioned as problematic for you. The ambiguity of "path" is actually functional.

Re: File system nomenclature. Death to path!
by repellent (Priest) on Aug 11, 2008 at 04:34 UTC
    I see things this way:

    • A $path is a definition that leads up to a $file.
    • A $dir is a $file.
    • A $file is something you can open and do a file test on.
    • $filename is loosely taken as the name that comes after the last $path separator.
    • $dirname is loosely taken as everything that comes prior to the last $path separator.
Re: File system nomenclature. Death to path!
by JavaFan (Canon) on Aug 11, 2008 at 08:56 UTC
    Your problem seems to be that you think that a path *is* a file or a directory.

    It isn't. In your example above, C:/www/domain/docroot/articles/2008/08/10/01.html is *not* a file, just like wfsp isn't a person. C:/www/domain/docroot/articles/2008/08/10/01.html is the "address" of a file, just like "wfsp" is the "address" of a person. Except that for people we call their addresses "names", and for files and directories, we call their addresses "paths".

Re: File system nomenclature. Death to path!
by Anonymous Monk on Aug 10, 2008 at 13:10 UTC
    I don't avoid anything, I simply don't find it confusing. I'm in favor of keeping the word path in the nomenclature.
Re: File system nomenclature. Death to path!
by doom (Deacon) on Aug 14, 2008 at 18:39 UTC

    If the question is "how do I keep things straight in the code that I write", the answer would be that I use the prefixes "full-" and "base-" a lot to indicate file names with and without paths (and if I were doing a lot with relative paths I would probably use "rel-" a lot). I also often use words like "location" or "loc" if I mean a directory without a file.

    If the question is, how do I keep this straight in the existing modules... well, one thing that helps is that I use templates to create new perl code and these templates already include the modules that I use most commonly, with an import list that specifies the routines I want most often. This makes at least *some* parts of the problem slightly easier: I don't need to remember which oddly-named module the "basename" function is stashed inside of, it's always just there.