in reply to File::Path::rmtree: What am I not grokking?

In a few words,
mkpath creates a directory, even if it's parent does not exist.
rmtree deletes a directory, even if it's not empty.

rmtree works like the unix commnd rm -r. It recursivly deletes children, not parents. In other words, it deletes a directory, whether it's empty or not. For example, using rmtree to delete /base/dir will delete /base/dir, /base/dir/a, /base/dir/a/1 and /base/dir/b.

I don't know of anything that does what you want with a single command.

And while we're talking about File::Path ... is the / following 'mkpath' and preceding 'foo' an error?

The leading slash makes it an absolute path. If you omit the leading slash, the path is relative to the current directory. Both are valid, but have different meanings.

Replies are listed 'Best First'.
Re^2: File::Path::rmtree: What am I not grokking?
by Aristotle (Chancellor) on Nov 02, 2005 at 22:06 UTC

    rmdir -p on Unices will work that way. If you say rmdir -p foo/bar/baz, it will remove foo/bar/baz, then foo/bar, and finally foo. However, it only works if these directories are all empty (since anything else wouldn’t make sense).

    I suppose this is about equivalent, except it also does an rm -r on the top of the path, so if you give it foo/bar/baz it will remove foo/bar/baz and will then remove foo/bar and foo as well if they turn out empty.

    use File::Path; use File::Spec::Functions qw( splitdir catdir ); sub rmtree_path { my ( $path ) = @_; rmtree $path; my @path = splitdir $path; do { pop @path } while @path and rmdir catdir @path; }

    Untested.

    Makeshifts last the longest.

Re^2: File::Path::rmtree: What am I not grokking?
by jkeenan1 (Deacon) on Nov 02, 2005 at 22:19 UTC
    I don't know of anything that does what you want with a single command.

    How about this?

    use File::Path; use File::Spec; use Test::More qw|no_plan|; my $tmp = "/Users/jimk/tmp"; chdir $tmp or die; my $partial = "alpha/beta/gamma"; mkpath($partial); ok(-d "$tmp/$partial", "$tmp/$partial created"); rmfromtop($partial); ok(! -d "$tmp/$partial", "$tmp/$partial deleted"); ok(! -d "alpha/beta", "alpha/beta deleted"); ok(! -d "alpha", "alpha deleted"); sub rmfromtop { rmtree((File::Spec->splitdir(+shift))[0]); }

    jimk

      I think you missed the point. It deletes much more than it should. For example, it will delete alpha/important. Also, it doesn't work with absolute paths.

      What’s the point? If you rmtree('alpha') it will recurse into all the subdirs anyway.

      Makeshifts last the longest.

        The point was that I didn't want to hardcode alpha. I wanted to supply the same, single variable to rmfromtop as I did to mkpath. And just as mkpath was creating a whole tree, I wanted a function to delete that same whole tree. Since this will be used in a testing context, I'm going to be creating the tree, verifying that I created it, deleting the tree, and verifying that I deleted it.

        jimk