Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

How do monks create paths?

by Cody Pendant (Prior)
on Apr 06, 2008 at 03:09 UTC ( #678596=perlquestion: print w/replies, xml ) Need Help??

Cody Pendant has asked for the wisdom of the Perl Monks concerning the following question:

When you have to create paths in your code from two or more strings, how exactly do you do it? Do you use trailing slashes, leading slashes, and why? Say for instance you have to programatically arrive at the path:
/Foo/bar/baz/bax.txt
by combining sub-paths, you could do it like this (assume that the strings are, or may be, variables):
my $path = '/Foo' . '/bar' . '/baz' . '/bax.txt';
or like this:
my $path = '/Foo/' . 'bar/' . 'baz/' . 'bax.txt';
and you can get away on some systems doing it like this:
my $path = '/Foo/' . '/bar/' . '/baz/' . '/bax.txt';
because double slashes aren't a problem.

Are there best practices, strong reasons for doing it one way and not another, platform gotchas, factional flame wars about the One True Way, etc?

I'm mostly asking because I have to do this quite often and every time I do it, I decide that one way is better than the other, then change my mind a day later. I'd appreciate some monastic wisdom to help me arrive at a Best Practice.



Nobody says perl looks like line-noise any more
kids today don't know what line-noise IS ...

Replies are listed 'Best First'.
Re: How do monks create paths?
by kyle (Abbot) on Apr 06, 2008 at 03:14 UTC

    There's File::Spec for doing this kind of thing portably. Most of the time, I just use slashes "as appropriate". Any path I have in a variable normally does not have a trailing slash. If it does, I consider that a special case, and it ends up eating part of my mind as I put effort into remembering it all the time. I suspect, however, that I just don't run into this kind of problem as often as you do, so I haven't come up with any practice that I'd swear by.

Re: How do monks create paths?
by perrin (Chancellor) on Apr 06, 2008 at 04:18 UTC
    use File::Spec::Functions qw(catfile); my $file = catfile(qw/ foo bar baz bax.txt /);
Re: How do monks create paths? (Path::Class)
by lodin (Hermit) on Apr 06, 2008 at 10:24 UTC

    Have you looked at Path::Class? If not you definately should check it out. I haven't used it much myself yet, but it looks nice and has great reviews at CPAN.

    Under the cover it uses File::Spec so it is portable. Here's an example using it on Windows:

    use Path::Class; my $path = file('', qw[ foo bar baz baz.txt ]); # The '' is to make it absolute. See comment in the doc. print $path, "\n"; print $path->as_foreign('Unix'), "\n"; __END__ \foo\bar\baz\baz.txt /foo/bar/baz/baz.txt

    lodin

Re: How do monks create paths?
by grep (Monsignor) on Apr 06, 2008 at 03:19 UTC
    For unixy stuff I use this. It gives me an absolute path without worrying about how trailing slashes were handled.
    sub abspath { # split anything that looks like a unix path seperator + my @tokens = map { defined $_ and split /\/+/ } @_; @tokens = grep { $_ ne '' } @tokens; return join( '/', '', @tokens ); }
    Which could adapted to use File::Basename which would handle other OS's.
    grep
    One dead unjugged rabbit fish later...
Re: How do monks create paths?
by Your Mother (Bishop) on Apr 06, 2008 at 05:18 UTC

    I also <3 File::Spec. If you want to know how to clear a path on the other hand, I suggest roaring, "I'll show you the life of the mind!"

Re: How do monks create paths?
by doom (Deacon) on Apr 06, 2008 at 22:29 UTC
    Other people have pointed you to File::Spec->catfile: that's the way to do it for portable code (e.g. something you expect to post to CPAN).

    What I do for local, unix-only hackery is: I never include a trailing slash on directories, and always build up new paths with double-quoted strings.

    A typical script might look something like this:

    use Env qw( $HOME ); use File::Path qw( mkpath ); use File::Basename qw( basename dirname fileparse ); use File::Copy qw( move copy ); my $some_file = shift; my $basename = basename( $some_file ); my $backup_location = "$HOME/backups"; mkpath( $backup_location ) unless -d $backup_location; my $new_file = "$backup_location/$basename.bak"; copy("$some_file", "$new_file") or die "got problems: $!";

    My personal opinion is that doing things like this is a win for readability:
    my $new_file = "$backup_location/$basename.bak";

    Also, note the stack of "use"s at the top... it's hard to do anything The Right Way in perl without leaning on the standard library a lot. These days I use script templates that include a dozen "use"s by default, so I don't have to try to remember what module "fileparse" is hidden inside of, and so on.

Re: How do monks create paths?
by Khen1950fx (Canon) on Apr 07, 2008 at 09:34 UTC
    I tried File::Util and File::Copy.

    #!/usr/bin/perl use strict; use warnings; use File::Util; use File::Copy "copy"; my ($f) = File::Util->new(); $f->make_dir('foo/bar/baz', '--if-not-exists'); copy('baz.txt', 'foo/bar/baz') or die "Copy failed: $!";

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://678596]
Approved by kyle
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2020-07-06 03:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?