Larry Wall wrote:

By all accounts, a s/// is an odd thing to put in a smart match
anyway.  You can't have a superposition of things with side effects,
for instance:

    $str =~ s/a/b/ | s/b/c/

Though doubtless Damian can think of something indeterminate to make
it mean.  :-)
Of course. That just superimposes the value in $str. For example:

	$str = "abc";
	$str =~ s/a/b/ | s/b/c/
	print eigenstates $str;     # "bbc", "acc"



The in-place really feels more like you want a method

    $str.s/a/b/
    @foo.s(1|2|3, {0})

or maybe

    $str.subst/a/b/
    @foo.subst(1|2|3, {0})
This is great, except for how much C<subst> looks like C<substr>.
Maybe:

      $str.replace/a/b/
      @foo.replace(1|2|3, {0})

???


Maybe the return value form is also a method:

    $result = $str.where/a/b/
    @result = @foo.where(1|2|3 -> {0})
I like the idea, but the keyword is wrong, I think. Too non-specific.
(No, I don't have a better one off the top of my head ;-)

I would, however, point out that other methods could
potentially have modify-in-place and a copy-and-modify
variants:

	@array.splice(2,0,$element);          # in-place
	@new = @array.splice(2,0,$element);   # on copy

	$str.chomp;                           # in-place
	$new = $str.chomp;                    # on copy

	$str.lcfirst;                         # in-place
	$new = $str.lcfirst;                  # on copy

	@array.map({ %trans{$^a} });          # in-place
	@new = @array.map({ %trans{$^a} });   # on copy

So we might want to look for a more general solution.

Unfortunately, one can't just generalize and use
void/non-void context to determine the correct behaviour,
since in-place matches and substitutions still need to
return their match object:

	$matched = $str.replace(/foo/ -> { 'bar' });  # in-place
	$newstr  = $str.replace(/foo/ -> { 'bar' });  # on copy

One could perhaps change the verb to a participle:

	@array.splice(2,0,$element);                   # in-place
	@new = @array.spliced(2,0,$element);           # on copy

	$str.chomp;                                    # in-place
	$new = $str.chomped;                           # on copy

	$str.lcfirst;                                  # in-place
	$new = $str.lcfirsted;                         # on copy

	@array.map({ %trans{$^a} });                   # in-place
	@new = @array.mapped({ %trans{$^a} });         # on copy

	$matched = $str.replace(/foo/ -> { 'bar' });   # in-place
	$newstr  = $str.replaced(/foo/ -> { 'bar' });  # on copy

but I doubt that would be well accepted. ;-)

Or one could define a copy-the-invoke method call operator (say, C<+.>):

	@array.splice(2,0,$element);                   # in-place
	@new = @array+.splice(2,0,$element);           # on copy

	$str.chomp;                                    # in-place
	$new = $str+.chomp;                            # on copy

	$str.lcfirst;                                  # in-place
	$new = $str+.lcfirst;                          # on copy

	@array.map({ %trans{$^a} });                   # in-place
	@new = @array+.map({ %trans{$^a} });           # on copy

	$matched = $str.replace(/foo/ -> { 'bar' });   # in-place
	$newstr  = $str+.replace(/foo/ -> { 'bar' });  # on copy


In typical topical string usage, that leaves us with

    if .subst/a/b/  {...}
    $result = .where/a/b/

That's quite livable, though the second is a bit odd, English-wise.
We could even keep around

    s/a/b/

as a shorthand for .subst/a/b/.
Oh, I definitely think so!


And maybe even add

    w/a/b/

as a synonym for .where/a/b/.
Hmmmmm. *s*ubstitute and *w*eplace. ;-)

Damian

Reply via email to