2017-07-25 49 views
4

我玩弄了一个字符串的位置界面。我知道How can I slice a string like Python does in Perl 6?,但我很好奇,如果我可以让这件事情只为咯咯笑。为什么Perl 6 Str做位置角色,我如何更改[]?

我想出了这个例子。阅读立场是好的,但我不知道如何设置了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 

我不认为这虽然会起作用。我不知道我应该做什么样的签名或特征。

为什么[]操作员在Str上工作?

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

的文档大多意味着[]工作的事情上做Positional角色,而这些东西都是一样的东西名单。从[] docs in operators

用于位置访问@container,a.k.a.“数组索引操作符”的零个或多个元素的通用接口。

但令人惊讶的Str做必要的角色,即使它不是一个@container(据我所知):

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

有没有一种方法来测试的东西是@container

有没有办法让事情列出它的所有角色?

现在,知道一个字符串可以响应[],我怎样才能找出什么签名将匹配?我想知道正确的签名用于定义我自己的版本,通过[]写入此字符串。实现这一

+0

但是,同样的事情也不会发生在例如'Int'中。它不会做位置。 –

+1

你滥用'.does' - 它期望一个类型对象(或者看[实现])(https://github.com/rakudo/rakudo/blob/43c1767/src/core/Mu.pm#L703 ('Positional')'等价于'“一些字符串”.does(Str)',而不是' “一些字符串”.does(Positional)' – Christoph

+0

然后'.does'应该抱怨那个。 –

回答

1

有一个模块,目的是让你这样做:

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

但是:

此模块不提供Str.AT-POS或使海峡型做阵地或可迭代的角色。后者由于内在假设Str类型不起这些作用而导致核心和非核心代码的各种后果。这意味着简单的英语是你只能使用postcircumfix操作符为你的字符串编制索引,并且不能将它们当作字符列表来处理 - 如果你需要的话只需调用.comb。`

3

要正确地使您rw版本的工作,你首先需要做哪些可能会也发生突变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" 

如果函数到达而不执行returnreturn-rw或抛出异常结束,则返回最后语句的值,和(目前),这表现为好像它是前面return-rw

sub identity2($x is rw) is rw { $x } 
identity2(my $w) = 42; # Works, $w is 42. 
相关问题