Why does Perl 6 Str act as a Positional and how can I change []?

I play with a positional interface for strings. I know. How can I slice a string like Python in Perl 6? but I was curious if I could make this thing work only for a giggle.

I came up with this example. The reading positions are fine, but I don’t know how to configure multito handle the assignment:

multi postcircumfix:<[ ]> ( Str:D $s, Int:D $n --> Str ) {
    $s.substr: $n, 1
    }
multi postcircumfix:<[ ]> ( Str:D $s, Range:D $r --> Str ) {
    $s.substr: $r.min, $r.max - $r.min + 1
    }
multi postcircumfix:<[ ]> ( Str:D $s, List:D $i --> List ) {
    map( { $s.substr: $_, 1 }, @$i ).list
    }

multi postcircumfix:<[ ]> ( Str:D $s, Int:D $n, *@a --> Str ) is rw {
    put "Calling rw version";
    }


my $string = 'The quick, purple butterfly';

{ # Works
my $single = $string[0];
say $single;
}

{ # Works
my $substring = $string[5..9];
say $substring;
}

{ # Works
my $substring = $string[1,3,5,7];
say $substring;
}

{ # NOPE!
$string[2] = 'Perl';
say $string;
}

The latter does not work:

T
uick,
(h   u c)
Index out of range. Is: 2, should be in 0..0
  in block <unit> at substring.p6 line 36

Actually thrown at:
  in block <unit> at substring.p6 line 36

I didn’t think it would work. I do not know what signature or features he should do, what I want to do.

Why []does the operator work on Str ?

$ perl6
> "some string"[0]
some string

, [] , Positional, , . [] docs :

@container, a.k.a.

a Str , @container ( ):

> "some string".does( 'Positional' )
True

, - @container?

-, ?

, , [], , ? , [].

+4
3

Str, AT-POS ( Str Any):

use MONKEY;
augment class Str {
    method AT-POS($a) {
        self.substr($a,1)
    }
}
say "abcde"[3]     # d
say "abcde"[^3]    # (a b c)

: https://docs.perl6.org/language/subscripts#Methods_to_implement_for_positional_subscripting

+7

rw , Str, rw, -, rw. :

multi postcircumfix:<[ ]> ( Str:D $s is rw, Int:D $i --> Str ) is rw {
   return $s.substr-rw: $i, 1;
}

rw Proxy:

multi postcircumfix:<[ ]> ( Str:D $s is rw, Int:D $i --> Str ) is rw {
   Proxy.new: FETCH => sub { $s.substr: $i },
       STORE => sub -> $newval { $s.substr-rw( $i, 1 ) = $newval }
}

, , return-rw, return.

sub identity( $x is rw ) is rw { return-rw $x }
identity( my $y ) = 42; # Works, $y is 42.

sub identity-fail( $x is rw ) is rw { return $x }
identity-fail( my $z ) = 42; # Fails: "Cannot assign to a readonly variable or a value"

, return, return-rw , ( ), , return-rw.

sub identity2( $x is rw ) is rw { $x }
identity2( my $w ) = 42; # Works, $w is 42.
+3

, :

https://github.com/zoffixznet/perl6-Pythonic-Str

:

This module does not provide Str.AT-POS or makes the Str type a job of Position or Iterable. The latter causes all kinds of drops with the kernel and non-core code due to the inherent assumptions that the Str type does not fulfill these roles. This means that you simply index your lines using the [...] postcircumfix operator and you cannot perforce treat them as lists of characters - just call .comb if you need it. `

+1
source

Source: https://habr.com/ru/post/1682174/


All Articles