http://www.perlmonks.org?node_id=220222

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

why does this gimme errors?
while (my @row = map { s/$term/"<i>$term</i>"/ } $sth->fetchrow_ar +ray()){ #do stuff here }
I simply want to highlight the search the term searched on in my sql query. The query works fine by itself, but when i want to map the results I run into problems.
thanks, am

Replies are listed 'Best First'.
(jeffa) Re: map DBI results
by jeffa (Bishop) on Dec 16, 2002 at 15:20 UTC
    map evalutes the last expression, so you are returning the number of substitions found by s///. Try this instead:
    while (my @row = map { s/$term/"<i>$term<\/i>"/; $_ } $sth->fetchrow_a +rray()) {
    You also need to escape the slash in </i>. Check out Map: The Basics for more examples on map.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: map DBI results
by slife (Scribe) on Dec 16, 2002 at 15:21 UTC

    While you haven't told us exactly what problems you are running into, I strongly suspect that this is it:

    map { s/$term/"<i>$term</i>"/ } ...

    Camel 3rd Ed p152 gives us:

    "The return value of an s/// operation (in scalar or list contexts alike) is the number of times it succeeded ..."

    You may want to consider something like this:
    map { s/$term/"<i>$term</i>"/; $_; } ...

Re: map DBI results
by Aristotle (Chancellor) on Dec 16, 2002 at 19:33 UTC
    Everybody explained why map doesn't mix too well with s/// and how you want a different delimiter than the forward slash there, but what I wonder is why you're using map at that point at all? It would be far simpler to say
    while (my @row = $sth->fetchrow_array()) { s!$term!"<i>$term</i>"! for @row; # ... }
    You also probably want to escape pattern metacharacters in $term (s!\Q$term!"<i>$term</i>"!, perldoc -f quotemeta), and it might help to precompile the pattern:
    my $rx = qr/\Q$term/; while (my @row = $sth->fetchrow_array()) { s!$rx!"<i>$term</i>"! for @row; # ... }

    Makeshifts last the longest.

Re: map DBI results
by diotalevi (Canon) on Dec 16, 2002 at 15:21 UTC

    And those problems are? How about doing us a favor and completing your question. Specify the required behaviour and the actual behaviour.

    Also ... on the off chance this is it you wrote your regular expression incorrectly. Try s{$term}{"<i>$term</i>"}. You used the forward slash character as your expression delimiter but also used it inside your expression as data. My fix just changes to a different delimiter. If this isn't the problem then you'll have to post again and clarify what the heck the problem was.


    Update: Oh yeah, and jeffa noticed that map is stomping on your return value. So the pattern is @target = map { s/foo/bar/; $_ } @source.


    Fun Fun Fun in the Fluffy Chair

Re: map DBI results
by runrig (Abbot) on Dec 16, 2002 at 19:12 UTC
    As already pointed out, one problem is your choice of s/// delimiter, but I'd also leave out the map:
    while (my @row = $sth->fetchrow_array) { s|$term|<i>$term</i>| for @row; ... }
      s|$term|<i>$term</i>|
      Ugh, please don't advise people to use pattern metacharacters such as pipes as delimiters. You're opening a large can of worms. It may be fine for obfuscation, but is only inviting pain anywhere else.

      Makeshifts last the longest.