http://qs321.pair.com?node_id=69155

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

my script does its foreach loops just fine, till i try to open another file in the middle of it, then it only hits the first ref found, then stops. how/where do i put the code (i marked below) where it can still read the refs @products, but won't interrupt the foreach? i've tried putting it in it's own "if" statement within the foreach loop, but it still stops the foreach loop.

foreach my $ref ( @products ) { if ($ref->{prodname} =~ ($value)) { print "<B>"; print $ref->{prodname}; print "</B>"; print "<br>"; print "<IMG SRC\=\"$ref->{img1}\">"; print "<br>"; print $ref->{prodprice}; print "<br>"; print "<a href\=\"shopper\.exe\?preadd\=action\&amp\;key\=$ref +->{prodcode}\">", "Add to Cart", "</a>"; #print $ref->{prodtext}; print "<br>"; print "<hr>"; ######This part stops my foreach loop my $textfile = "$ref->{prodname}"; open (INF, $textfile) or die "Can't open file"; my @scoop = <INF>; close (INF); print "@scoop"; ######### } }

Replies are listed 'Best First'.
Re: foreach interruption
by lachoy (Parson) on Apr 03, 2001 at 05:04 UTC

    There are a few things we can fix:

    foreach my $ref ( @products ) { # Try using the standard regex delimiters (if you use # '()' then you must use a 'm' in front) if ($ref->{prodname} =~ /$value/ ) { # Use the good things about Perl! Heredocs are # easy to use and understand print <<PROD; <B>$ref->{prodname}</B><br> <IMG SRC="$ref->{img1}"><br> $ref->{prodprice}<br> <a href="shopper.exe?preadd=action;key=$ref->{prodcode}"> Add to Cart</a><br> <hr> PROD # Why don't we try to check the error returned and # see what file we were opening? my $textfile = $ref->{prodname}; eval { open (INF, $textfile) || die "Can't open file ($textfile): $!" }; if ( $@ ) { print "Found an error!\n$@\n"; } else { my @scoop = <INF>; close (INF); print "@scoop"; } } }

    Tracing what you're actually trying to do is usually all the debugging you need :-)

    Chris
    M-x auto-bs-mode

Re: foreach interruption
by chromatic (Archbishop) on Apr 03, 2001 at 06:24 UTC
    I don't understand what you mean by 'interrupts'. As far as I can see, the only way that will happen is if the file cannot be found. In that case, you'll get an error message, which you didn't mention. (If you did get the error message, please post it!)

    If I were you, I would print the contents of @products to a log file before the loop, or at least the number of elements (print scalar @products) to verify that it contains what you think it contains.

    I might also write your open code as:

    open(INF, $ref->{prodname) or die "Can't open $$ref{prodname}: $!"; print while <INF>; close INF;
    ... but I can't see where that will have a great effect.
Re: foreach interruption
by malaga (Pilgrim) on Apr 03, 2001 at 05:36 UTC
    yes, that's good. i was testing for the existence of the file by substituting an actual filename, but this is better. BUT, i get the same problem, it still interrrupts my foreach loop. it only returns one product instead of the whole list i should be getting.
Re: foreach interruption
by malaga (Pilgrim) on Apr 03, 2001 at 07:00 UTC
    what i mean by interrupt, is this: my foreach loop runs and prints out a list of products that match the keyword. it works great. there are about 20 items that match. then, when i add the section that opens the file to dump some text that correcsponds to each item, it works fine but it stops after only one item. it no longer gives me all 20. am i explaining it right?
      Have you turned warnings on? I've seen behavior somewhat similar to that when a script attempts to reference an undefined variable, though the only variable defined outside of your snippet seems to be $ref->{prodname}. That seems like a fairly important variable, so I assume you've already checked it's value is correct. But in any case, since the bug is limited to that section, just remove all the lines them add them back individually until it breaks. Try just opening and closeing first, then add the file read, then the prints.

      BTW, thread continuity is helped greatly by attaching replies to specific comments to that comment. Click on the reply's title to go to its node, then use the "Comment on..." link.