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

Dear monks,

My input is a list with names following this pattern (in fact, matching the pattern is not my real issue):

1-PVC_0
2-PVC_0
2-PVC_1
etc...

I need to replace this list with a list of "features" of those names, that come as the output of a function, say function1. I have done this with the following code:
@newlist = grep (s/(\d+-PVC_\d+)/ &function1($1)/e, @oldlist);
So far, so good. What if I want to replace each item with a string that is the concatenation of the result of function1, of the character "/" and the result of another function, function2. Then using this code:
@newlist = grep (s/(\d+-PVC_\d+)/ &function1($1) \/ &function2($1)/e, +@oldlist);
(of course) gives me the result of a division :-) How can I use s// with /e but in a way that evaluates, then quotes, then evaluates again?

Hope my problem statement was clear and I am not giving anyone a headache...
Athanasia

Update:
Sometimes, the obvious just does not pass from one's mind... However, I learned something new, that is the "map" function. Thanks to all those who responded!

Replies are listed 'Best First'.
Re: s// with e option : evaluate, quote, evaluate
by Fletch (Bishop) on Mar 31, 2009 at 13:49 UTC

    Hint: how would you concatenate the return from two sub calls in a normal not-inside-an-s/// expression?

    (Unrelated, but prefixing your calls with & isn't necessary and may subtly change how the call behaves (see perlsub for the gory details).)

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: s// with e option : evaluate, quote, evaluate
by Limbic~Region (Chancellor) on Mar 31, 2009 at 13:53 UTC
    athanasia,
    You use the string concatenate operator . - see perlop.

    To take this further, your grep should probably be a map. You likely shouldn't be using &fun(@arg) unless you know what the & is doing. Also, for anything more complex - you probably should use a block:

    for my $thing (grep defined, @oldlist) { if (/(\d+-PVC_\d+)/) { my $item = $1; my $str1 = foo($item) || ''; my $str2 = bar($item) || ''; push @newlist, $str1 . '/' . $str2; } else { warn "Do not know what '$thing' is\n"; } }

    Cheers - L~R

Re: s// with e option : evaluate, quote, evaluate
by ikegami (Patriarch) on Mar 31, 2009 at 14:00 UTC

    I need to replace this list with a list of "features" of those names, that come as the output of a function

    Then you need map, not grep. However, s/// doesn't play well with either unless precautions are taken, so it's simpler to use for here.

    my @newlist = @oldlist; s{(\d+-PVC_\d+)}{ function1($1) . '/' . function2($1) }e for @newlist;

    You were clobbering @oldlist.