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


in reply to How to build system calls using '=>'

I appreciate that you're just using "mkdir -p" as an example here... but for any passers by who are hunting for a way to make a path of directories they would be better following blue_cowdawg's advice in Re: "mkdir -p" equivalent? and using mkpath in File::Path

If they have a reason they can't use File::Path (even though it's a core module these days) they would be better using the built-in mkdir than shelling out to a system one.

use strict; use warnings; my $seperator = '/'; # Change this for a non-Unix compatible OS my @dirs = ("some/long/dir/path"); for my $path ( @dirs ) { my @path = split($seperator, $path); my $cat_path; for my $dir (@path) { $cat_path .= $dir; unless ( -d $cat_path ) { mkdir ( $cat_path ) || die "Can't mkdir '$cat_path': $!\n"; print "mkdir: created directory `$cat_path'\n"; } $cat_path .= $seperator; } }
and Three has dealt with some of the problems faced by Windows users in Re: Perl API that emulates mkdir -p on unix? (yes, for *Windows*) :o)

Replies are listed 'Best First'.
Re^2: How to build system calls using '=>'
by Perl Mouse (Chaplain) on Dec 14, 2005 at 14:21 UTC
    ..or any passers by who are hunting for a way to make a path of directories they would be better following blue_cowdawg's advice in Re: "mkdir -p" equivalent? and using mkpath in File::Path
    I always wonder how useful statements like "it's better to use X instead of Y" are if they don't say why X is better.

    I'll bite. I say using the systems 'mkdir' is better than 'mkpath' because the arguments of 'mkpath' are hard to remember (without looking in the docs, what's the second argument of mkpath? How do I tell mkpath which mode I need? How do I create multiple directories in one go?). On top of that, 'mkpath' has a different name than 'mkdir'.

    Sure, if you work on a system that doesn't have 'mkdir', you're better off to use File::Path. But then, programming in such an environment is like writing a novel without using the letter 'e'.

    If they have a reason they can't use File::Path (even though it's a core module these days) they would be better using the built-in mkdir than shelling out to a system one.
    And then you present a 17 line piece of code, which has a OS dependency as well, doesn't have an option to set a mode, and is verbose without an option to turn it off.

    I strongly prefer to shell out using one line, have the ability to set the mode, and which, by default, is silent.

    Perl --((8:>*
      Why: mkpath doesn't require an external binary, doesn't create another process to do its job, and has full control over what it's doing and what comes back - there are less places that the attempt to create a directory can go wrong.

      Re remembering: The link to blue_cowdawg's advice in Re: "mkdir -p" equivalent? is there specifically because it *shows* an example of how to use mkpath, including modes etc - so they don't *have* to remember.

      The 17 line piece of code is an _example_. It is verbose so that the user knows where to report if they need to do so, they can always comment out the print, but it's where it is so they know if they want to report, that's *where* they should do it, i.e. it should only say it's done it once it's worked and not before.

      Shelling out to 'mkdir -p $path' is OS dependent as well - if you do that on Windows (tested on xp) you will end up with a directory called "-p" as well. In the example it points out *where* to change the directory seperator.

      mkdir allows you to set the mode as well, if you wish to - fair call, perhaps I could have added that in the example. :o)

        mkpath doesn't require an external binary
        Eeeck! Scary! An external binary! Code reuse! Bad! Bad! Bad!

        Perl is a glue language. There's nothing wrong with using a code someone else wrote. Whether that's "an external binary" (what's an "internal binary"?) or a module.

        doesn't create another process to do its job
        Yes, and? Are you worried about performance? Sure, creating another process takes a few microseconds. But we're about the muck around in the filesystem anyway. And compiling a piece of Perl isn't exactly resource free either.
        so they don't *have* to remember.
        Yeah, but then they have to look it up. And that takes valuable programmer time.
        Shelling out to 'mkdir -p $path' is OS dependent as well
        I never claimed it wasn't.
        The 17 line piece of code is an _example_.
        Of course. But:
        system 'mkdir', '-p', @dirs and die;
        is just one line. Even if you mimic it using 5 lines, it's still 400% more lines. Remember: programmer time is expensive!
        Perl --((8:>*