Piers Cawley writes:

> Stéphane Payrard <[EMAIL PROTECTED]> writes:
> 
> >  s/// in string context should return the string after substituion.
> 
> Surely it should return the string after substitution, but with an
> appropriate 'but true' or 'but false' property depending on whether
> anything was substituted.

Perl 5 C<s///g> currently returns the number of substitutions made.
This has its uses, so Perl 6 C<s:e///> should probably continue to do
this.

Can we have a return value that stringifies to the result of the
substitution but numifies to the number of substitutions made and
boolifies based on the number rather than the string (to allow for
situations such as a successful substitution producing an empty string)?

Would we want that anyway?  It means there's a difference between:

  $substituted = $text ~~ s/$pattern/$replacement/;
  if $substituted

and:

  if $text ~~ s/$pattern/$replacement/

which doesn't sound like a great feature to leave lying around in a
language.

Thinking about this some more, I'm not convinced about Stéphane's claim.
Is it useful to return the substituted string?  We already have the
substituted string in one variable (C<s///> doesn't work on a constant), so
what's the point in having it in a second one?

Often I want to modify a string and leave the _original_ behind in a
separate variable:

  (my $modified = $original) ~~ s/$pattern/$replacement/;

but that's different, because the two variables end up with
(potentially) different contents rather than always being duplicates.

This, however, is irritating:

  my @new = map { s:e/$pattern/$replacement/; $_ } @old;

I forget the C<; $_> far more often than I like to admit and end up with
an array of integers instead of modified strings.  So I'd like a more
elegant way of writing that -- but I don't think making the return value
of C<s///> more complicated (and duplicating data in the process) would
be a nett gain.

It seems that the substituted text is needed only either in the original
variable or somewhere else, but not both.  A variant of C<s///> which
did not modify the original but did return the modified string could
have some use.  That'd allow things such as:

  my $modified = $original ~~ ss/$pattern/$replacement/;

  my @new = map { ss:e/$pattern/$replacement/ } @old;

except that C<ss///> is obviously a lousy name for such an operator.
I've no idea what a good name would be for distinguishing between
'modify yourself in this way and return how many times you did it' and
'return a copy of yourself modified in this way'; I fear that it'd be
too easy to get these confused and do the wrong thing.[*0]

Having an operator that substitutes and returns the modified string
would certainly have its uses, but unless a way can be found of doing
this which doesn't make other things worse, we'd just be rearranging the
inconveniences and introducing new pitfalls; on balance I think I'd
rather keep the pitfalls that I'm already used to avoiding than fix
those but have to learn about new ones.

  [*0]  I suppose it could be seen as analogous to the difference
  between C<$count + 2> and C<$count += 2>.  So maybe that's a precedent
  for such distinctions and it wouldn't be that confusing after all
  (C<~~> and C<~~=> anybody?).  Or maybe the fact that learners often
  get those different sorts of addition confused is a reason for not
  going any further along this route and making matters worse.

Smylers

Reply via email to