ベアボーンソリューション
シーケンスの要点を印刷するための非常にシンプルなソリューションから始めましょう。それはあなたがあなたの質問に追加した詳細を扱いませんが、それは良い出発点です:
sub seq-range-gist ( @seq ) {
  my @pairs = @seq.pairs;
  join "\n", @pairs.head(3)».gist, '...', @pairs.tail(2)».gist
}
とは異なり.kv、その呼び出し元をフォームに変換しますkey1, value1, key2, value2, key3, value3, ...。つまり、その呼び出し元が3つの要素を含む場合、6つの要素は、.pairsその呼び出し元をフォームに変換しkey1 => value1, key2 => value2, key3 => value3, ...ます。
一部の.pairs代わりに使用しまし.kvた。これは».gist、後でコード内で使用するだけで、key1 => value1各要素の表示を簡単にできるようになるためです。以下で変更しますが、これは慣用的な出発点として適切です。
通話は(;よりカ月でそのことについて、それは怠惰ではありません提供)インボカントリストから最初と最後のN個の要素の小さなリストを作成するための慣用的な方法です。.head.tail
この最初のソリューションが与えられると、次のようにsay seq-range-gist (0,1 ... Inf)[^10]表示されます。
0 => 0
1 => 1
2 => 2
...
8 => 8
9 => 9
次に、「最初の要素だけを...印刷された出力から削除する」ことができるようにしたいと思います。残念ながらsay seq-range-gist (0,1 ... Inf)[1..9]表示されます:
0 => 1
1 => 2
2 => 3
...
7 => 8
8 => 9
の左側の=>番号に元のシーケンスの番号付けを保持させたい。これを有効にするには、抽出する範囲から基になるシーケンスを分割します。2番目のパラメーター/引数@rangeを追加[@range]し、サブの2行目に追加します。
sub seq-range-gist ( @seq, @range ) {
  my @pairs = @seq.pairs[@range];
これでsay seq-range-gist (0,1 ... Inf), 1..9、表示を書き込むことができます。
1 => 1
2 => 2
3 => 3
...
8 => 8
9 => 9
あなたの質問では、aINDEX =  VALUEではなく形式を使用しましたINDEX => VALUE。要旨のカスタマイズを可能にするために、3番目の&gistルーチンのパラメーター/引数を追加し、組み込み.gistメソッドの代わりにそれを呼び出します。
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 の本体の「メソッド」呼び出しが、.&gistではなくになって.gistいることに注意してください。構文.&fooはsubを 呼び出し&foo(通常はjustを書き込むことで呼び出されますfoo)、その左側の呼び出し元を引数.としてsubに渡し$_ます。
また、&gistパラメータの前にを付けて、パラメータを名前付きのものにしたことにも注意してください:。
だから今say seq-range-gist (0,1 ... Inf), 1..9, gist => { "a{.key} =  {.value}" }表示されます:
a1 =  1
a2 =  2
a3 =  3
...
a8 =  8
a9 =  9
ポリッシュを追加する
この答えの残りは、磨きを気にする読者のためのボーナス資料です。
say seq-range-gist (0, 1, 2, 3), ^3 表示:
0 => 0
1 => 1
2 => 2
...
1 => 1
2 => 2
おっとっと。また、ヘッドとテールの組み合わせよりも多くのペアがあったとしても、少なくともラインが繰り返されなかったとしても、head, ..., tail1つまたは2つの要素だけを削除するアプローチを使用しても意味がありません。サブボディの最後のステートメントを変更して、これらの問題を排除しましょう。
  join "\n",
    @pairs < $head + $tail + 3   # Of course, the 3 is a bit arbitrary
      ?? @pairs».&gist
      !! (@pairs.head($head)».&gist, '...', @pairs.tail($tail)».&gist)
次に、範囲または要旨なしで呼び出された場合、サブが何か便利なことをするといいでしょう。@rangeと&gistパラメータに適切なデフォルトを与えることで、ほとんどの場合それを修正できます。
sub seq-range-gist (
  @seq,
  @range = @seq.is-lazy ?? ^100 !! ^@seq,
  :&gist = { .gist }
) {
@seqが遅延でない 場合、デフォルトでの全範囲になります。が無限の場合(この場合も遅延です)、最大100のデフォルトで問題ありません。しかし、怠惰であるにもかかわらず、定義された値が100未満の場合はどうなりますか?このケースをカバーするために、宣言に追加します。@range@seq@seq@seq.grep: *.value.defined@pairs
  my @pairs = @seq.pairs[@range].grep: *.value.defined;
別の単純な改善は、オプションのヘッドとテールのパラメーターであり、最終的な洗練されたソリューションにつながります。
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)
}