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

Hello Monks, I encountered a problem (I have a solution), but I thought that someone may be able to explain exactly what is going on. I was using Path::Class::Dir with the make_path method from the File::Path module. I had started with code like this:
use File::Path; use Path::Class::File; my $pcd = Path::Class::Dir->new('test_dir', 'test_subdir'); make_path($pcd, { verbose => 1 })
With the above code, the path would get created and my script would succeed. When I no longer wanted verbose output, I deleted the { verbose => 1 } hashref.
use File::Path; use Path::Class::File; my $pcd = Path::Class::Dir->new('test_dir', 'test_subdir'); make_path($pcd)
This code would fail (the path would not be created). I assume this has something to do with the context of $pcd in the make_path call, but I would be interested in a more precise explanation. If I force the stringification of $pcd (with $pcd->stringify or "$pcf" then it works again). Here is a more extensive lists of tests.
#!/usr/bin/env perl use strict; use warnings; use File::Path qw/make_path remove_tree/; use Path::Class; my $t_dir = 'test_dir'; my $t_subdir = 'test_subdir'; my $pcd = Path::Class::Dir->new($t_dir, $t_subdir); # Test1 make_path($pcd); if ( -e $pcd ) { print "make_path(\$pcd) worked!\n"; } else { print "make_path(\$pcd) did NOT work\n"; } remove_tree($t_dir); # I know this works, use it for cleanup # Test2 make_path($pcd, {}); if ( -e $pcd ) { print "make_path(\$pcd, {}) worked.\n"; } else { print "make_path(\$pcd, {}) did NOT work.\n"; } remove_tree($t_dir); # Test3 my $t_dir_pcd = Path::Class::Dir->new($t_dir); make_path($pcd, {}); # I know this works, use it to create path before + removal attempt remove_tree($t_dir_pcd); if ( -e $t_dir_pcd ) { print "remove_tree(\$pcd) did NOT work.\n"; } else { print "remove_tree(\$pcd) worked.\n"; } remove_tree($t_dir); # Actually remove the tree # Test4 make_path($pcd, {}); remove_tree($t_dir_pcd, {}); if ( -e $t_dir_pcd ) { print "remove_tree(\$pcd, {}) did NOT work.\n"; } else { print "remove_tree(\$pcd, {}) worked.\n"; } remove_tree($t_dir); # Actually remove the tree # Test5 make_path($pcd->stringify); if ( -e $pcd ) { print "make_path(\$pcd->stringify) worked\n"; } else { print "make_path(\$pcd->stringify) did NOT work\n"; } remove_tree($t_dir); # Actually remove the tree #Test6 make_path($pcd, {}); remove_tree($t_dir_pcd->stringify); if ( -e $t_dir_pcd ) { print "remove_tree(\$t_dir_pcd->stringify) did NOT work.\n"; } else { print "remove_tree(\$t_dir_pcd->stringify) worked.\n"; } remove_tree($t_dir); # Actually remove the tree # Test7 make_path("$pcd"); if ( -e $pcd ) { print "make_path(\"\$pcd\") worked\n"; } else { print "make_path(\"\$pcd\") did NOT work\n"; } remove_tree($t_dir); # Actually remove the tree #Test8 make_path($pcd, {}); remove_tree("$t_dir_pcd"); if ( -e $t_dir_pcd ) { print "remove_tree(\"\$t_dir_pcd)\" did NOT work.\n"; } else { print "remove_tree(\"\$t_dir_pcd\") worked.\n"; } remove_tree($t_dir); # Actually remove the tree exit;
Giving the following output:
make_path($pcd) did NOT work make_path($pcd, {}) worked. remove_tree($pcd) did NOT work. remove_tree($pcd, {}) worked. make_path($pcd->stringify) worked remove_tree($t_dir_pcd->stringify) worked. make_path("$pcd") worked remove_tree("$t_dir_pcd") worked.

Replies are listed 'Best First'.
Re: Problem when using Path::Class::File with File::Path ( dir()->mkpath(
by Anonymous Monk on Jul 18, 2013 at 07:32 UTC

    You're typing too much

    #!/usr/bin/perl -- use strict; use warnings; use Path::Class qw/ dir file /; use Data::Dump qw/ dd pp /; my $goner = dir('temp3k'); my $gonee = dir( $goner, 'ro/sham/bo' ); $gonee->mkpath( { verbose => 1 } ); $gonee->rmtree( { verbose => 1 } ); $gonee->mkpath( { verbose => 0 } ); $goner->rmtree( { verbose => 1 } ); __END__ mkdir temp3k mkdir temp3k\ro mkdir temp3k\ro\sham mkdir temp3k\ro\sham\bo rmdir temp3k\ro\sham\bo rmdir bo rmdir sham rmdir ro rmdir temp3k

    I imagine the behaviour you're seeing because dir() is a blessed hash

    $ perl -le " use Data::Dump; use Path::Class; dd( dir( ) ); bless({ dirs => ["."], file_spec_class => undef, volume => "" }, "Path +::Class::Dir")

    And File::Paths checks to see if its a hash and it is, so its used as \%opt