Barebone çözümü
Bir sekansın özünü yazdırmak için çok basit bir çözümle başlayalım. Sorunuza eklediğiniz özelliklerle ilgilenmiyor, ancak iyi bir başlangıç noktası:
sub seq-range-gist ( @seq ) {
my @pairs = @seq.pairs;
join "\n", @pairs.head(3)».gist, '...', @pairs.tail(2)».gist
}
.kvInvocanını forma dönüştürenlerin aksine , key1, value1, key2, value2, key3, value3, ...invocan 3 element içeriyorsa 6 element, .pairsinvosanını forma dönüştürür key1 => value1, key2 => value2, key3 => value3, ....
Bunun .pairsyerine .kvkısmen kullandığım ».gistiçin, kodda daha sonra key1 => value1her öğeye zahmetsizce güzel bir ekran almak için kullanabileceğim anlamına geliyordu . Bunu aşağıda değiştireceğiz, ancak bu iyi bir deyimsel başlangıç.
.headve.tail çağrılar bir invocant listeden ilk ve son N elemanlarının küçük listeleri oluşturmak için deyimsel yoludur (o tembel değil sağlanan; daha bu konu hakkında bir mo).
Bu ilk çözüm verildiğinde aşağıdakileri say seq-range-gist (0,1 ... Inf)[^10]görüntüler:
0 => 0
1 => 1
2 => 2
...
8 => 8
9 => 9
Daha sonra, "sadece ilk öğeyi ... basılı çıktıdan düşürmek" istiyoruz. Ne yazık ki say seq-range-gist (0,1 ... Inf)[1..9]görüntüler:
0 => 1
1 => 2
2 => 3
...
7 => 8
8 => 9
Solundaki sayının =>orijinal dizinin numaralandırmasını korumasını istiyoruz . Bunu etkinleştirmek için temel diziyi ayıklamak istediğimiz aralıktan ayırırız. İkinci bir parametre / bağımsız değişken ekliyoruz ve alt @rangeöğenin [@range]ikinci satırına ekliyoruz :
sub seq-range-gist ( @seq, @range ) {
my @pairs = @seq.pairs[@range];
Şimdi say seq-range-gist (0,1 ... Inf), 1..9görüntülemek için yazabiliriz :
1 => 1
2 => 2
3 => 3
...
8 => 8
9 => 9
Sorunuzda biçimi kullanmak aINDEX = VALUEyerine kullandınız INDEX => VALUE. Gist'in özelleştirilmesine izin vermek için üçüncü bir &gistrutin parametre / argüman ekliyoruz ve bunu yerleşik .gistyöntem yerine çağırıyoruz :
sub seq-range-gist ( @seq, @range, :&gist ) {
my @pairs = @seq.pairs[@range];
join "\n", @pairs.head(3)».&gist, '...', @pairs.tail(2)».&gist
}
seq-range-gistSub gövdesindeki "yöntem" çağrılarının şimdi nasıl olduğuna .&gistdikkat edin .gist. Sözdizimi .&foobir çağırır alt &foo (tipik olarak, sadece yazılı çağrılır foosolunda invocant geçen) .bir şekilde $_alt argüman.
Ayrıca &gistparametrenin bir ile başlayarak adlandırılmış bir tane yaptığımı unutmayın :.
Şimdi say seq-range-gist (0,1 ... Inf), 1..9, gist => { "a{.key} = {.value}" }görüntülenir:
a1 = 1
a2 = 2
a3 = 3
...
a8 = 8
a9 = 9
Lehçe ekleme
Bu cevabın geri kalanı lehçeyi önemseyen okuyucular için bonus materyal.
say seq-range-gist (0, 1, 2, 3), ^3 görüntüler:
0 => 0
1 => 1
2 => 2
...
1 => 1
2 => 2
Hata. Ve kafa ve kuyruktan daha fazla çift olsa bile, en azından tekrarlanan çizgiler alamadık, head, ..., tailsadece bir veya iki elementi elide etme yaklaşımını kullanmak yine de anlamsız olurdu . Bu sorunları ortadan kaldırmak için alt gövdedeki son ifadeyi değiştirelim:
join "\n",
@pairs < $head + $tail + 3 # Of course, the 3 is a bit arbitrary
?? @pairs».&gist
!! (@pairs.head($head)».&gist, '...', @pairs.tail($tail)».&gist)
Sonra, alt aralık veya gist olmadan çağrılırsa yararlı bir şey yapsaydı iyi olurdu. Bunu çoğunlukla @rangeve &gistparametrelerine uygun varsayılanlar vererek düzeltebiliriz :
sub seq-range-gist (
@seq,
@range = @seq.is-lazy ?? ^100 !! ^@seq,
:&gist = { .gist }
) {
Eğer @seqbir değil tembel sonra, @rangetam kapsamlı varsayılan @seq. Eğer @seqbir sonsuz (bu durumda o da tembeldir), sonra 100 kadar varsayılan gayet iyi. Peki ya @seqtembel ancak 100'den az tanımlanmış değer verirse ne olur ? Bu vakayı kapsamak .grep: *.value.definediçin @pairsbildirime ekliyoruz:
my @pairs = @seq.pairs[@range].grep: *.value.defined;
Başka bir basit gelişme, isteğe bağlı kafa ve kuyruk parametreleri olacak ve nihai cilalı bir çözüme yol açacaktır:
sub seq-range-gist (
@seq,
@range = @seq.is-lazy ?? ^100 !! ^@seq,
:$head = 3,
:$tail = 2,
:&gist = { .gist }
) {
my @pairs = @seq.pairs[@range].grep: *.value.defined;
join "\n",
@pairs <= $head + $tail + 2
?? @pairs».&gist
!! (@pairs.head($head)».&gist, '...', @pairs.tail($tail)».&gist)
}