キャプチャを動的に作成する方法(Raku)


8

次の例では、配列(@a)をキャプチャーに「変換」することにより、キャプチャーを動的に作成しようとしています。

コードを考えてみましょう:

sub f (|c){
    say '';
    say '  List : ' ~ do {c.list.gist if c.list.elems > 0};
    say '  Hash : ' ~ do {c.hash.gist if c.hash.elems > 0};
    say '';
}

my $c1 = \(1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9);

my @a  =   1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9;
my $c2 = \(|@a);

f(|$c1);

f(|@a);
f(|$c2);

結果は次のとおりです。

  List : (1 (2 3) 4 5 6 7 8 9)
  Hash : Map.new((t1 => test1, t2 => test2))


  List : (1 (2 3) 4 5 t1 => test1 6 7 t2 => test2 8 9)
  Hash : 


  List : (1 (2 3) 4 5 t1 => test1 6 7 t2 => test2 8 9)
  Hash : 

最初の実行(Capture $ c1を使用)は必要に応じて実行され、望ましい動作が生成されます。Captureを動的に作成する2番目と3番目の試行は失敗しています(おそらく、これらの場合のサブルーチンfの引数が目的のCaptureではないためです)。配列@aに組み込まれたペアは、リストのメンバーであると見なされ、名前付きパラメーターではないようになっていることがわかります。

サブルーチンfに渡す前に、配列内のペアの「平坦化」が行われている必要があることを知っていますが、その方法を理解できません。

誰かが私にヒントを与えることはできますか?

回答:


7

クラスListにはメソッドCaptureがあります。これは、希望どおりに機能します。

my $c  = \(1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9);
my @a  =   1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9;
my $c2 = @a.Capture;
f(|$c);
f(|$c2);
f(|@a);
sub f (|c){
    say() ;
    say '  List : ', c.List;
    say '  Hash : ', c.Hash;
    say();
}

関数の定義を変更fして、リストを直接操作できます@a

my $c  = \(1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9);
my @a  =   1,(2,3),4,5, :t1('test1'), 6,7, :t2('test2'), 8,9;
f($c);
f(@a);
sub f (Capture(Any) \c){
    say() ;
    say '  List : ', c.List;
    say '  Hash : ', c.Hash;
    say();
}

Capture(Any)いわゆる強制タイプです。受け入れますAnyが、強制しますCapture。つまり、(繰り返し)メソッドCaptureを呼び出して取得します。

また、Captureパターンマッチングを利用することができます。したがって、関数の最後の定義は次のfように変更できます。

sub f ( (**@list, *%hash) ) {
#or even sub f ( (*@list, :t1($t),*%hash) ) {
    say() ;
    say '  List : ', @list;
    # say ' test1 : ', $t;
    say '  Hash : ', %hash;
    say();
}  

2番目のソリューションが機能する理由をもう少し説明できますか?
ジャカル

1
回答の最後に説明を追加しました。
wamba

Foo(Any)タイプとして使用している場合は、おそらく単にを使用できますFoo()。私はあなたが取るAnyが、そうでないわけではない時間を想像することはできませんAny Mu
user0721090601
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.