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

Hi Monks, I'm having issues with the following code. "job types..." gets printed, as well as the $temp_jobvar,$quick_jobtype..., but it never reaches $sortby, or "starting build lists..." and I have no idea why. It runs through the loop and prints out all the temp_jobvars and quick_jobtype, but when they match it just keeps going. If you look at the print statements below you'll see my notes...
@jobvar_list=(); @jobname_list=(); @jobnice_list=(); $n = 0; @jobvar_list[$n] = "senior"; @jobname_list[$n] = " Senior"; $n++; @jobvar_list[$n] = "exec"; @jobname_list[$n] = " Executive"; $n++; $quick_build="listing"; $quick_jobtype="exec"; print "job types...<br>\n"; #(THIS GETS PRINTED) for ($st=0; $st<=@jobvar_list-1; $st++) { $temp_jobvar = @jobvar_list[$st]; print "$temp_jobvar, $quick_jobtype...<br>\n"; #( THESE GET PRINTE +D AS THE LOOP GOES THROUGH) if (($quick_jobtype && ($quick_jobtype eq $temp_jobvar)) || (!$qui +ck_jobtype)) { #if ($quick_jobtype eq $temp_jobvar) { #ALTERNATE IF STATEMENT THAT + ALSO DOESN'T WORK $jobvar = $temp_jobvar; $jobname = @jobname_list[$st]; $groupfile = $jobvar; $grouptitle = $jobname; $sortby = " WHERE jobtype like '%$jobvar%' and active='yes' AND jo +bstatus!='suspend' ORDER BY dateadded DESC, jobtitle ASC"; print "$sortby"; #(THIS DOES NOT GET PRINTED) print "starting build lists<br>\n"; #(THIS DOES NOT GET PRINTED) $building_cat = "yes"; &Build_Lists_Both; } # end if ($cat1 eq $cat_db_var) } # end for ($st=1; $st<=$jobvar_list; $st++)
I can't figure out why it doesn't go through. I've even changed the IF statement and it doesn't work either. I'm stumped.

Replies are listed 'Best First'.
Re: Help with a loop
by Preceptor (Deacon) on Jun 14, 2013 at 21:34 UTC

    First rule of fixing broken perl code. Apply 'use strict;' and 'use warnings;'. This gives a lot of warnings and errors with your code, which would warrant sorting first.

    It looks like you're doing a fairly substantial number of slightly horrible things. I would imagine that if you did use strict and warnings, your problem would vanish (or become obvious. For starters - populating an array by setting $n.

    my @jobvar_list = ( "senior", "exec" );

    Will do exactly the same thing. Even better, you could use a hash, so you never needed to iterate through one list, and reference another list.

    my %jobvar_list = ( 'senior' => 'Senior', 'exec' => 'Exec' ); my $quick_jobtype = "exec"; foreach my $temp_jobvar ( keys %jobvar_list ) { print "$temp_jobvar, $jobvar_list{$temp_jobvar}\n"; if ( $temp_jobvar eq $quick_jobtype ) { print "$temp_jobvar matches $quick_jobtype"; my $sortby = " WHERE jobtype like '%$jobvar%' and active='yes' AND + jobstatus!='suspend' ORDER BY dateadded DESC, jobtitle ASC"; print $sortby; } }

    I think it must be that 'if' clause that's causing you problems - what is it trying to do? It sounds like it's evaluating but never working, and therefore not running that 'sortby' and 'Build_Lists_Both' segments of code. Which is odd, because it seems to be doing so in that sample code you posted. Is there any chance that you've tidied your code up a bit, with the job title list? that 'eq' line means that the two variables have to match precisely - no whitespace or linefeeds. Because your code _does_ run as is.

      Monks, Thanks so much! I didn't write this code originally, but edited it to fit what I needed, but I'm an amateur. Thanks for all the suggestions (most of which are above my head). Preceptor solved it for me with this: "that 'eq' line means that the two variables have to match precisely - no whitespace or linefeeds. " I changed it to:
      if (($quick_jobtype && ($quick_jobtype =~ /$temp_jobvar/)) || (!$quick +_jobtype)) {
      and IT WORKS! Once again the Monks have saved me. Thanks.

        As you're maintaining the code, a rewrite is probably a good idea - there really is nothing like code that's not quite correct to give you all manner of headaches down the line (despite working now)

Re: Help with a loop
by space_monk (Chaplain) on Jun 14, 2013 at 21:22 UTC

    You are not initialising the arrays correctly

    my @jobvar_list=qw/senior exec/; my @jobname_list=( " Senior", " Executive" ); my $n = @jobname_list; # length
    They might be better as a hash anyway...the following code shows roughly how as well as some other changes...
    my %jobs = ( 'senior' => ' Senior', 'exec' => ' Executive' ); my $quick_build='listing'; my $quick_jobtype='exec'; print "job types...<br>\n"; foreach my $key (keys %jobs) { print "$key, $quick_jobtype...<br>\n"; my $jobvar = $key; my $jobname = $jobs{$key}; if (($quick_jobtype && ($quick_jobtype eq $jobvar)) || (!$quick_jo +btype)) { $groupfile = $jobvar; $grouptitle = $jobname; # heredocs are quite good for SQL... $sortby = <<EOF; WHERE jobtype LIKE '%$jobvar%' AND active='yes' AND jobstatus!='suspen +d' ORDER BY dateadded DESC, jobtitle ASC EOF print "$sortby"; print "starting build lists<br>\n"; my $building_cat = "yes"; # I don't know what this function does # but pass parameters to it, don't use global variables. # e.g. Build_Lists_Both( $sortby, $building_cat, $groupfile ) +; } # end if ($cat1 eq $cat_db_var) } } # end for ($st=1; $st<=$jobvar_list; $st++)
    If you spot any bugs in my solutions, it's because I've deliberately left them in as an exercise for the reader! :-)
Re: Help with a loop
by frozenwithjoy (Priest) on Jun 14, 2013 at 21:25 UTC

    A few comments:

    You should be using: use warnings; and use strict;, because they will reveal a lot of errors (e.g., Scalar value @jobvar_list[$n] better written as $jobvar_list[$n] at ...

    I added these and made the necessary changes (including declaring everything with my ... and re ran it (after commenting out the subroutine that gets called) and it seems to work fine:

    #!/usr/bin/env perl use strict; use warnings; my @jobvar_list = (); my @jobname_list = (); my @jobnice_list = (); my $n = 0; $jobvar_list[$n] = "senior"; $jobname_list[$n] = " Senior"; $n++; $jobvar_list[$n] = "exec"; $jobname_list[$n] = " Executive"; $n++; my $quick_build = "listing"; my $quick_jobtype = "exec"; print "job types...<br>\n"; for ( my $st = 0 ; $st <= @jobvar_list - 1 ; $st++ ) { my $temp_jobvar = $jobvar_list[$st]; print "$temp_jobvar, $quick_jobtype...<br>\n"; if ( ( $quick_jobtype && ( $quick_jobtype eq $temp_jobvar ) ) || ( !$quick_jobtype ) ) { my $jobvar = $temp_jobvar; my $jobname = $jobname_list[$st]; my $groupfile = $jobvar; my $grouptitle = $jobname; my $sortby = " WHERE jobtype like '%$jobvar%' and active='yes' AND jobstatus!='susp +end' ORDER BY dateadded DESC, jobtitle ASC"; print "$sortby"; print "starting build lists<br>\n"; my $building_cat = "yes"; # &Build_Lists_Both; } # end if ($cat1 eq $cat_db_var) } # end for ($st=1; $st<=$jobvar_list; $st++) __END__ job types...<br> senior, exec...<br> exec, exec...<br> WHERE jobtype like '%exec%' and active='yes' AND jobstatus!='suspend' + ORDER BY dateadded DESC, jobtitle ASCstarting build lists<br>

    Also, you can write your for loop in a more readable manner like this:

    #OLD: for ( my $st = 0 ; $st <= @jobvar_list - 1 ; $st++ ) { for my $st ( 0 .. $#jobvar_list ) {