Search code examples
for-looprakuread-writerakudo-star

perl6/rakudo: Problem with writing on the loop-variable


#!perl6
use v6;

my $longest = 3;
my @list = <a b c d e f>;

for @list -> $element is rw {
    $element = sprintf "%*.*s", $longest, $longest, $element;
    $element.say;
}

This works. But in the second and third I get an error-message. How could I make them work?

#!perl6
use v6;

my $longest = 3;
my @list = <a b c d e f>;

for @list <-> $element {
    $element = sprintf "%*.*s", $longest, $longest, $element;
    $element.say;
}

# ===SORRY!===
# Missing block at line 11, near ""

.

#!perl6
use v6;

my $longest = 3;
my $list = <a b c d e f>;

for $list.list -> $element is rw {
    $element = sprintf "%*.*s", $longest, $longest, $element;
    $element.say;
}

# Cannot modify readonly value
#   in '&infix:<=>' at line 1
#   in <anon> at line 8:./perl5.pl
#   in main program body at line 1

Solution

  • Regarding your second example

    The <-> may not have worked in the Rakudo Perl you used, but it has been fixed in more recent versions. (It had to do with a deep parsing issue that required a better longest-token-matching algorithm than we had at that time.)

    Regarding your third example

    The statement

    my $list = <a b c d e f>;
    

    creates $list as a Seq data type, and Seq elements are considered to be immutable. What you really want is for $list to become an Array, as in:

    my $list = [<a b c d e f>];
    

    With that in place, the last example works as expected:

    pmichaud@orange:~/rakudo$ cat x.p6
    #!perl6
    use v6;
    
    my $longest = 3;
    my $list = [<a b c d e f>];
    
    for $list.list -> $element is rw {
        $element = sprintf "%*.*s", $longest, $longest, $element;
        $element.say;
    }
    
    pmichaud@orange:~/rakudo$ ./perl6 x.p6
      a
      b
      c
      d
      e
      f
    pmichaud@orange:~/rakudo$ 
    

    Hope this helps!

    Pm