Perl 6で動的に名前付き引数を指定する

こんにちは19日目の投稿になります。

今日は、Perl 6で動的に名前付き引数を指定する方法を紹介しようと思います。

下記は、挨拶を行うプログラムです。
perl6で名前付き引数に対して代入を行う場合は、通常`name => "ラリー"` (#1)や、`:name("ラリー")` (#2)といった形で代入を行います:

```
use v6;                                                                                                                    
use Test;                                                                                                                  
                                                                                                                           
sub greeting(Str :$name = "noname", Int :$hours = 8 --> Str) {                                                             
    sprintf("こんにちは %s さん。今日も %d 時間労働頑張るぞい。\n", $name, $hours);                                        
}                                                                                                                          
                                                                                                                           
is greeting, "こんにちは noname さん。今日も 8 時間労働頑張るぞい。\n"; # ok                                                  
is greeting(name => "ラリー"), "こんにちは ラリー さん。今日も 8 時間労働頑張るぞい。\n"; # ok (#1)                                 
is greeting(:name("ラリー"), :hours(12)), "こんにちは ラリー さん。今日も 12 時間労働頑張るぞい。\n"; # ok (#2)     

done-testing;                
```

ここで、ラリーさん以外にも挨拶を行うことを考えましょう。下記のような名前-労働時間のペアを新たに追加することを考えます:

+ ザ・企業戦士のラクダさんは20時間労働
+ 時短労働のカメリアさんは4時間労働
+ 定時退社しないと気が済まないパンプキンさんは7時間労働

そうすると、コードは下記のようになります:

```
is greeting(:name("ラリー"), :hours(8)), "こんにちは ラリー さん。今日も 8 時間労働頑張るぞい。\n"; # ok (※ラリーさんは2人いる)
is greeting(:name("ラリー"), :hours(12)), "こんにちは ラリー さん。今日も 12 時間労働頑張るぞい。\n"; # ok
is greeting(:name("ラクダ"), :hours(20)), "こんにちは ラクダ さん。今日も 20 時間労働頑張るぞい。\n"; # ok                      
is greeting(:name("カメリア"), :hours(4)), "こんにちは カメリア さん。今日も 4 時間労働頑張るぞい。\n"; # ok                   
is greeting(:name("パンプキン"), :hours(7)), "こんにちは パンプキン さん。今日も 7 時間労働頑張るぞい。\n"; # ok 
```

ちょっと冗長じゃないかなあと思った方もいるかと思います。
実はPerl6では引数の内容をいったん別の変数に格納しておいて、あとから使うこともできます。
そうするともっと簡潔に書けそうですよね。
具体的には、`|`とハッシュを使って上記のコードと等価なコードを書くことができます:

```
my @options = [ 
    {:name("ラリー")},                                                                                                          
    {:name("ラリー"), :hours(12)},                                                                                         
    {:name("ラクダ"), :hours(20)},                                                                                         
    {:name("カメリア"), :hours(4)},                                                                                        
    {:name("パンプキン"), :hours(7)}                                                                                       
];                                                                                                                         
                                                                                                                           
for @options -> %option (Str :$name = "noname", Int :$hours = 8) {                                                                        
    is greeting(|%option), "こんにちは $name さん。今日も $hours 時間労働頑張るぞい。\n"; # ok (#1)
}  
```

+ この例では、`|%option`でHashを名前付き引数に変換しています。 (#1)

どうでしょうか。だいぶ簡潔に書けるようになったと思います。
Pairにおいても同等のことができます。詳しくは次のページを参照ください: https://docs.perl6.org/type/Signature#Positional_vs._Named

以上、19日目の投稿でした。