2017-07-25 81 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. 
相關問題