views:

94

answers:

1

Well, the title says it all. Small example:

perl -e '$s="aaabbcc";$c=()=$s=~/a/g;print"$c\n$s\n"' (m//g) outputs

3
aaabbcc

whereas perl -e '$s="aaabbcc";$c=()=$s=~s/a/x/g;print"$c\n$s\n"' (s///g) outputs

1
xxxbbcc

I'd like to do both things at once without having to match first: substitute and know the number of substitutions. Obviously a s///g does not return the number of substitutions in scalar context--unlike m//g does with matches. Is this possible? If yes, how?

perlre, perlvar and perlop provided no help (or I just couldn't find it).

+7  A: 

s/// does return the number of substitutions made in scalar context. From perlop (emphasis added):

s/PATTERN/REPLACEMENT/msixpogce
Searches a string for a pattern, and if found, replaces that pattern with the replacement text and returns the number of substitutions made. Otherwise it returns false (specifically, the empty string).

Your problem is that you didn't call s/// in scalar context. You called it in list context and then evaluated the assignment (to an empty list) in scalar context. A list assignment in scalar context returns the number of elements produced by the right-hand side of the expression. Since s/// returns a single value (in both list and scalar context) the number of elements is always one even if the s/// didn't do anything.

perl -E "$s='aaabbcc'; $c=()=$s=~s/x/y/g; say qq'$c-$s'"  # prints "1-aaabbcc"

To call s/// in scalar context, omit the =()= pseudo-operator.

perl -E "$s='aaabbcc'; $c=$s=~s/a/x/g; say qq'$c-$s'"  # prints "3-xxxbbcc"
Michael Carman
Actually, he did not evaluate the list in scalar context. That is impossible. He evaluated the **list assignment** in scalar context.
daotoad
@daotoad: Thanks, I knew it wasn't quite right but the terminology escaped me for a moment. Tangent: Why don't more people use their editing ability to just fix details like that?
Michael Carman
I can't reflect on the motivations of others, but I don't edit what other people write in any way that changes the intent or meaning. For example, there are some people who are passionate about their belief in the existence of "lists in scalar context" in Perl, if you were one of these people, it would be very offensive for me to put words into your mouth that disavow your (erroneous and putative) belief. There are also cases where **my** understanding is in error, and changing the post would make it wrong. For these reasons, I prefer to point out errors rather than "fix" them. YMMV
daotoad
Under the Perl tag, there has been a lot of fixing of "errors" in questions which alters the question so that it answers itself.
Kinopiko
In retrospect my question is rather embarrassing. Don't know why I didn't find it in the obvious doc... it has been a long day I suppose. Obviously I thought `m//` and `s///` should behave similar in respect to their evaluation in scalar or list context which is wrong. Anybody care to enlighten me why 'scalar evaluation of list' is wrong? Because even 'Programming Perl' uses exactly that expression (3rd edition, 2.8.2).
musiKk
daotoad
@daotoad: I confused lists and arrays... again. This is something I still don't completely grasp despite a few years of occasional Perl usage. I'll have to read up on that. Also thanks for the link to perlmonks, this discussion sounds interesting. Good for a quiet Friday night. Thanks a lot for your help (all of you).
musiKk