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

I have successfully been able to assign separate filehandles to scalers, search and return results, however, both file search results return in both placeholders. I need to assign a $line3 to $main_template =~ s %%searcresults%%/$pitem/g; and $line2 to $main_template =~ s %%premiumresults%%/$premiumitem/g;
$main_template =~ s/%%keywords%%/$fields{'keywords'}/g; $main_template =~ s/%%searcresults%%/$pitem/g; $main_template =~ s/%%premiumresults%%/$premiumitem/g;
$pitem and $premiumitem only represent the HTML file insertion names and are not relevant here. I am thinking I need an if, elsif and else statement somewhere so that $main_template =~ s/%%searcresults%%/$pitem/g; is assgned with $line3 if the results are found in SIDX, that $main_template =~ s/%%premiumresults%%/$premiumitem/g; is assigned with $line2 if the results are found in SIDX2, and that both are returned if the results were found in both SIDX and SIDX2.
foreach $item (@skeyw){$nrkeywords++;} open (SIDX, "$data_dir/search.idx"); open (SIDX2, "$data_dir/search2.idx"); if ($file_locking ne "No"){flock (SIDX, LOCK_SH) or die "Can't set lo +ck for file: $data_dir/search.idx, $data_dir/search2.idx $!\n";} while($line3 = [SIDX]) { $line2 = [SIDX2]; $sline = "${line1}${line2}${line3}"; foreach $kwr (@skeyw) { if (($sline =~ /$kwr/i) and ($kwr ne "")) $toadk = "true"; } } if ($toadk eq "true") { $premium_resultline[$icnt] = "${line2}"; $resultline[$icnt] = "${line3}"; $toadk = false; $icnt++; } } #if ($file_locking ne "No"){flock (CIT, LOCK_UN);} close (SIDX); close (SIDX2); } $main_template = html::insert_tmpl_includes($main_template); print "$main_template"; exit;

Replies are listed 'Best First'.
Re: Assigning scalars to scalar template includes
by dws (Chancellor) on Jun 30, 2004 at 06:41 UTC

    First a few comments about the meta-problem: I had a rather difficult time understanding what it was you were asking for, in part because the title was misleading, in part because the problem statement included extraneous material that obscured the question, and a bit because the code fragment won't run.

    To get good answers to your questions here, it really helps to:

    1. Trim your question down to the essentials. Here that means leaving off details of what you are able to get working, especially if you find yourself noting that parts are relevant.
    2. Provide working--or at least compiling--code, by copy/pasting a fragement into <code></code> blocks rather than retyping. In the example above, <SIDX> became [SIDX], which is plainly not what you intended.
    3. Trim your examples down to the essentials that illustrate the problem. Here, the locking bits are just clutter.

    As to your problem as I'm able to discern it from the code: You're walking two flat index files in parallel. For each pair of index lines, you attempt to find matches with as may keywords as possible, recording matches. The code shows that @resultline and @premium_results grow in parallel, with potential duplicates if multiple keywords match against either line. (I suspect this isn't what you want, and perhaps the nature of your index files prevents it.)

    I'm guessing that you want to be doing something like the following, and I'm changing names to make the code clearer:

    use strict; my(@results, @premium_results); open(RESULTS, "$data_dir/search1.idx") or die "$data_dir/search1.idx: $!"; while ( $line = <RESULTS> ) { foreach my $keyword ( @keywords ) { if ( $line =~ /\b$keyword\b/ ) { push @results, $line; last; } } close(RESULTS); open(PREMIUM, "$data_dir/search2.idx") or die "$data_dir/search2.idx: $!"; while ( $line = <PREMIUM> ) { foreach my $keyword ( @keywords ) { if ( $line =~ /\b$keyword\b/ ) { push @premium_results, $line; last; } } } close(PREMIUM);

    This builds up @results and @premium_results independently, while ensuring that keywords match entire words (if this isn't what you want, remove the \b's), and ensuring that a line is only recorded once if any keyword matches. Nothing in the code you showed suggests that the two index files need to be walked in parallel. And if the first index is smaller than the second, you risk false negatives on the extra, unread lines in the second index.

    A simple refactoring--left as an exercise--is to take the two largely common code block and make them a subroutine that takes a filename as input and returns an array of matching lines as output.

      The code you gave me works great. What I am trying to do is: If keywords are found in <RESULTS> only then:
      $main_template =~ s/%%searcresults%%/$pitem/g;
      If keywords are found in <PREMIUM> only then:
      $main_template =~ s/%%premiumresults%%/$premiumitem/g;
      If keywords are found in both <RESULTS> and <PREMIUM> then:
      $main_template =~ s/%%searcresults%%/$pitem/g; $main_template =~ s/%%premiumresults%%/$premiumitem/g;

        What I am trying to do is: ...

        O.K., but what do you want to do with $main_template if there are no results? Leave %%searchresults%% there? Or do you want to erase it? I assume you want to erase it.

        Here's enough of a start that you should be able to figure the rest out yourself:

        # join results into a single variable; this may be empty my $results = join('', @results); # do the substitution. $main_template =~ s/%%searchresults%%/$results/g;