Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Loop stops at first iteration

by props (Hermit)
on Dec 28, 2007 at 05:07 UTC ( [id://659300]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks

Symptom: "In the following loop only the first instance of $folder gets executed.The loop ends thereafter".

My case is similar to this thread 658908. The following script grabs all rar files from input directory then extracts each file in the output directory. Using the mp3splt command i split the mp3 files accordingly. Some folder name editing happens in the end.
foreach my $folder (@folders) { next if $folder =~ /^\.\.?/; my $fqname = catdir( $output, $folder ); if ( -d $fqname ) { if ( ( glob("$fqname/*.cue") ) ) { print "$fqname: cue found\n"; } else { print "$fqname: cue found\n"; my ($cue) = <$fqname/*.cue>; my ($mp3) = <$fqname/*.mp3>; &process( $cue, $mp3, $fqname ); remove qw(*.cue *.m3u *nfo *.sfv); &renameFolder($folder);

full code

use warnings; use strict; use File::Remove qw(remove); use File::Spec::Functions; my $input = '/mnt/music/input/'; my $output = '/mnt/music/output/'; opendir DIR, $input or die "cannot open DIR: $!\n"; my @rars = grep /\.rar$/i, readdir(DIR); closedir(DIR); chdir($output) or die "error chmod to /output: $!"; foreach my $rar (@rars) { &extract($rar); } opendir( OUTPUT, $output ) or die "error open OUTPUT\n"; my @folders = readdir(OUTPUT) or die "error read folders\n"; closedir(OUTPUT); foreach my $folder (@folders) { next if $folder =~ /^\.\.?/; my $fqname = catdir( $output, $folder ); if ( -d $fqname ) { # assuming i have 2 folders with each one hosting a cue file # only the first cue file will be found if ( ( glob("$fqname/*.cue") ) ) { print "$fqname: cue found\n"; } else { print "$fqname: cue found\n"; my ($cue) = <$fqname/*.cue>; my ($mp3) = <$fqname/*.mp3>; &process( $cue, $mp3, $fqname ); remove qw(*.cue *.m3u *nfo *.sfv); &renameFolder($folder); } } } sub extract { my $file = shift; my @args = ( "unp", "$input$file" ); system(@args) == 0 or die "cannot extract: $!\n"; } sub process { my $cue = shift; my $mp3 = shift; my $folder = shift; my @args = ( "mp3splt", "-c", "$cue", "$mp3", "-o", '@n_@a_@b_@t' +); system(@args) == 0 or die "system @args failed: $?"; remove $mp3; chdir $output; } sub renameFolder { my $folder_before = shift; for ( my $folder_after = $folder_before ) { s/_-_/_/; s/-PsyCZ//; s/-UPE//; s/-mAhA//; s/-/_/; rename( $folder_before, $folder_after ); } }

Replies are listed 'Best First'.
Re: Loop stops at first iteration
by ikegami (Patriarch) on Dec 28, 2007 at 05:39 UTC

    You're using glob in scalar context without fetching all the results from it.

    By the way, your regex is equivalent to /^\./. You're skipping everything that starts with a .. You want /^\.\.?\z/.

      let's unfold my brain thoughts: i did some minor changes from previous code:
      foreach my $folder (@folders) { # for instance folder1 next if ($folder eq "."); next if ($folder eq ".."); my $fqname = catdir( $output, $folder ); #$fqname is /mnt/music/output/folder1 if ( -d $fqname ) { #passed the test if (glob("$fqname/*.cue")) { # yes there is /mnt/music/found/output/folder1/a.cue print "$fqname: cue found\n"; #prints: /mnt/music/found/output/folder1/: cue found my ($cue) = <$fqname/*.cue>; # my ($cue) grabs /mnt/music/output/folder1/a.cue } elsif(!glob(("fqname/*.cue"))) { print "$fqname: no cue found\n"; next; } } }
      I understand that every loop grabs one element in the @folder array and executes the subroutine. Each iteration is unique and it doesn't have to remember the previous executions. my ($cue) = <$fqname/*.cue>; gets a different cue file on every iteration. Now if it has to do with the context of glob and I push @cues , ($cue) i will have an array of cue files in @cues. So how i will be helped by this approach?
        In scalar context, glob iterates through such filename expansions, returning undef when the list is exhausted.
        for (1..4) { if (glob($0)) { print("I exist\n"); } else { print("I don't exist\n"); } }

        outputs

        I exist I don't exist I exist I don't exist

        if (glob(...)) is wrong. The only time glob should be in scalar context is in while (glob(...)), and the loop better not execute last, return or die.

        Fix:

        for (1..4) { if (() = glob($0)) { print("I exist\n"); } else { print("I don't exist\n"); } }

        or

        for (1..4) { if (-e $0) { print("I exist\n"); } else { print("I don't exist\n"); } }
        I exist I exist I exist I exist

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-03-29 05:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found