为什么 Perl 6 Str 扮演位置角色,我如何更改 []?
Why does a Perl 6 Str do the Positional role, and how can I change []?
我正在研究字符串的位置接口。我知道 How can I slice a string like Python does in Perl 6?,但我很好奇我是否可以让这个东西只为咯咯笑而工作。
我想到了这个例子。阅读位置很好,但我不知道如何设置 multi
来处理作业:
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;
}
最后一个不行:
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
虽然我不认为它会起作用。我不知道它应该有什么签名或特征来做我想做的事。
为什么 []
operator work on a Str?
$ perl6
> "some string"[0]
some string
文档主要暗示 []
可以处理 Positional roles and that those things are in list like things. From the []
docs in operators:
Universal interface for positional access to zero or more elements of a @container, a.k.a. "array indexing operator".
但是 Str
令人惊讶地发挥了必要的作用,即使它不是 @container
(据我所知):
> "some string".does( 'Positional' )
True
有没有办法测试某物是 @container
?
有没有办法让某物列出其所有角色?
现在,知道字符串可以响应 []
,我怎样才能确定哪个签名会匹配它?我想知道用于定义我自己的版本以通过 []
.
写入此字符串的正确签名
实现此目的的一种方法是扩充 Str
class,因为您实际上只需要重写 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.raku.org/language/subscripts#Methods_to_implement_for_positional_subscripting
有一个模块旨在让您执行此操作:
https://github.com/zoffixznet/perl6-Pythonic-Str
但是:
This module does not provide Str.AT-POS or make Str type do Positional or Iterable roles. The latter causes all sorts of fallout with core and non-core code due to inherent assumptions that Str type does not do those roles. What this means in plain English is you can only index your strings with [...] postcircumfix operator and can't willy-nilly treat them as lists of characters—simply call .comb if you need that.`
为了使您的 rw
版本正常工作,您首先需要制作可能也会发生变异的 Str rw
,并且它需要 return 反过来也是rw
。对于字符串的特定情况,您可以简单地执行:
multi postcircumfix:<[ ]> ( Str:D $s is rw, Int:D $i --> Str ) is rw {
return $s.substr-rw: $i, 1;
}
通常,您需要一个 rw
子例程到 return 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
或抛出异常就到达了结尾,最后一条语句的值是 returned,并且(目前),这就像在 return-rw
.
之前一样
sub identity2( $x is rw ) is rw { $x }
identity2( my $w ) = 42; # Works, $w is 42.
我正在研究字符串的位置接口。我知道 How can I slice a string like Python does in Perl 6?,但我很好奇我是否可以让这个东西只为咯咯笑而工作。
我想到了这个例子。阅读位置很好,但我不知道如何设置 multi
来处理作业:
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;
}
最后一个不行:
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
虽然我不认为它会起作用。我不知道它应该有什么签名或特征来做我想做的事。
为什么 []
operator work on a Str?
$ perl6
> "some string"[0]
some string
文档主要暗示 []
可以处理 Positional roles and that those things are in list like things. From the []
docs in operators:
Universal interface for positional access to zero or more elements of a @container, a.k.a. "array indexing operator".
但是 Str
令人惊讶地发挥了必要的作用,即使它不是 @container
(据我所知):
> "some string".does( 'Positional' )
True
有没有办法测试某物是 @container
?
有没有办法让某物列出其所有角色?
现在,知道字符串可以响应 []
,我怎样才能确定哪个签名会匹配它?我想知道用于定义我自己的版本以通过 []
.
实现此目的的一种方法是扩充 Str
class,因为您实际上只需要重写 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.raku.org/language/subscripts#Methods_to_implement_for_positional_subscripting
有一个模块旨在让您执行此操作:
https://github.com/zoffixznet/perl6-Pythonic-Str
但是:
This module does not provide Str.AT-POS or make Str type do Positional or Iterable roles. The latter causes all sorts of fallout with core and non-core code due to inherent assumptions that Str type does not do those roles. What this means in plain English is you can only index your strings with [...] postcircumfix operator and can't willy-nilly treat them as lists of characters—simply call .comb if you need that.`
为了使您的 rw
版本正常工作,您首先需要制作可能也会发生变异的 Str rw
,并且它需要 return 反过来也是rw
。对于字符串的特定情况,您可以简单地执行:
multi postcircumfix:<[ ]> ( Str:D $s is rw, Int:D $i --> Str ) is rw {
return $s.substr-rw: $i, 1;
}
通常,您需要一个 rw
子例程到 return 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
或抛出异常就到达了结尾,最后一条语句的值是 returned,并且(目前),这就像在 return-rw
.
sub identity2( $x is rw ) is rw { $x }
identity2( my $w ) = 42; # Works, $w is 42.