16

I've combed the docs but I can't seem to find how to do this in perl6.

In perl5 I would have done (just an example):

sub func { ... }

$str =~ s/needle/func($1)/e;

i.e. to replace 'needle' with the output of a call to 'func'

jjmerelo
  • 22,578
  • 8
  • 40
  • 86
iPherian
  • 908
  • 15
  • 38

2 Answers2

15

There is no e modifier in Perl 6; instead, the right hand part is treated like a double-quoted string. The most direct way to call a function is therefore to stick an & before the function name and use function call interpolation:

# An example function
sub func($value) {
    $value.uc
}

# Substitute calling it.
my $str = "I sew with a needle.";
$str ~~ s/(needle)/&func($0)/;
say $str;

Which results in "I sew with a NEEDLE.". Note also that captures are numbered from 0 in Perl 6, not 1. If you just want the whole captured string, pass $/ instead.

Jonathan Worthington
  • 29,104
  • 2
  • 97
  • 136
13

Ok so we'll start by making a function that just returns our input repeated 5 times

sub func($a) { $a x 5 };

Make our string

my $s = "Here is a needle";

And here's the replace

$s ~~ s/"needle"/{func($/)}/;

Couple of things to notice. As we just want to match a string we quote it. And our output is effectively a double quoted string so to run a function in it we use {}. No need for the e modifier as all strings allow for that kind of escaping.

The docs on substitution mention that the Match object is put in $/ so we pass that to our function. In this case the Match object when cast to a String just returns the matched string. And we get as our final result.

Here is a needleneedleneedleneedleneedle
Scimon Proctor
  • 4,558
  • 23
  • 22
  • 1
    "needle" can of course be an actual regex and it works fine with that too. – Scimon Proctor May 10 '19 at 12:31
  • 1
    Hi Scimon. Nice quick clean answer. `"needle"` could also be `needle`, without the quotes. Presumably you chose/prefer to quote it for clarity? – raiph May 10 '19 at 12:48