in reply to Re^6: getting a while loop to terminate
in thread getting a while loop to terminate

After giving it a bit more thought, I realized that the only "acceptable" error from mkdir (the only one you want to continue looping after) is EEXIST (File exists). So maybe it makes more sense to loop on that error. That eliminates the need for any flags, or any extra error checking to avoid a race condition:

$my $counter = 1; use Errno qw[ EEXIST ]; sub mk_new_dir { while(1){ my $name = $word . '_' . $counter++; if( mkdir $name, 0755 ){ return $name; # success, return new dir name } else { next if $!{EEXIST}; # mkdir failed because the file exists; loop + and try next name die $!; # it failed for some other reason; bail out! } } }

Aaron B.
My Woefully Neglected Blog, where I occasionally mention Perl.

Replies are listed 'Best First'.
Re^8: getting a while loop to terminate
by Aldebaran (Curate) on Apr 19, 2012 at 02:49 UTC

    I thought I posted the final version of this. I've been reading as I come here and noticed that it's a possibility that if your thread dithers on too long, someone might just cut it off. I don't know whether that happened, or I just forgot to click the create button, but I don't think a thread has finished until one has a version with a bit of polish:

    $ perl tg6.pl downloaded 83 images from http://www.yahoo.com to folder site_4 $ cat tg6.pl #!/usr/bin/perl -w # creates a new directory and downloads images from url to it # perlmonks node 965537; thx aaron and A.M. use strict; use feature ':5.10'; use WWW::Mechanize; use LWP::Simple; use Errno qw[ EEXIST ]; # get information about images my $domain = 'http://www.yahoo.com'; my $m = WWW::Mechanize->new(); $m->get( $domain); my @list = $m->images(); # create new folder and download images to it. my $counter = 0; my $dir = &mk_new_dir; for my $img (@list) { my $url = $img->url_abs(); $counter++; my $filename = $dir. "/image_". $counter; getstore($url,$filename) or die "Can't download '$url': $@\n"; } # output print "downloaded ", $counter, " images from ", $domain, "\n"; print "to folder ", $dir, "\n"; sub mk_new_dir { my $counter2 = 1; while(1){ my $word = "site"; my $name = $word . '_' . $counter2++; if( mkdir $name, 0755 ){ return $name; # success, return new dir name } else { next if $!{EEXIST}; # mkdir failed because the file exists die $!; # it failed for some other reason; bail out! } } $

    I think aaron's integrating the 'mkdir $name, 0755' as the truth condition of the sub is great, as well as the post-increment of $counter2 to drive the thing forward.

    }

      I prefer to use  die sprintf "(%d) %s", $!, $!; because the frequent Unknown Error isn't very useful :)