Juerd writes:
> Perlists,
>
> In Perl 5, lc, lcfirst, quotemeta, uc and ucfirst don't mutate.
> chomp and chop do mutate.
>
> I imagine these will all be methods in Perl 6:
>
> $foo.lc
> $foo.quotemeta
> $foo.chomp
>
> I'd like a mutating version of lc, and a non-mutating version of chomp.
> With some nice syntax, if possible.
>
> If there isn't already such a thing in the making, I hereby suggest to
> re-introduce C<.=>, to mean more or less the same as in Perl 5, but with
> Perl 6's version of the C<.> operator.
I believe this has been discussed before, and that people generally
liked it. Maybe Larry even did (I seem to recall him saying something
positive about it -- but don't think he did just because I said so :-).
It seems likely that this will go in, though.
I'm in the mood for an exercise, so, here's how you implement it.
Let's say we have the Perl grammar:
grammar Perl
{
# ...
has %.assignment_ops is protected;
rule assignment_expression {
<assignment_lhs>
$op := (%.assignment_ops.keys())
$value := <%.assignment_ops{$op}{rule}>
{
$0 := %.assignment_ops{$op}{transform}($0)
if %.assignment_ops{$op}{transform}
}
}
rule method_call {
<term> <'.'> <method_name>
}
}
Or something. I'm just pulling that out of my ear.
Then we'll derive our own grammar with the C<.=> operator in, and plunk
it into Perl's parser.
grammar DotEqualsPerl is Perl
{
submethod BUILD() {
.assignment_ops{'.='} = {
rule => /<method_name>/,
transform => {
Perl::assignment_expression.new(
lhs => .{assignment_lhs},
rhs => Perl::method_call.new(
term => .{assignment_lhs},
method => .{value},
)
)
},
};
}
}
Finally, hooking it into Perl.
use grammar DotEqualsPerl;
Again, this is quite presumptuous about the workings of the Perl::*
classes. The Perl grammar will have to be extremely well documented.
The reason we couldn't just decalre it with C<infix:.=> is because its
right hand side is not a usual expression. That is:
$foo + bar;
Won't parse unless C<bar> is a declared sub, whereas:
$foo.bar;
Will always parse.
Luke