当 Raku 中给定块内时,如何与值列表进行智能匹配?

uzl*_*xxx 7 pattern-matching raku

我发现了这个 JS 代码片段:

function append(demo = "", file = "") {
    const extra = "ctl=1&embed=1";
    if (demo && file)  return `/${demo}/?file=${file}&${extra}`;
    if (!demo && file) return `/?file=${file}&${extra}`;
    if (demo && !file) return `/${demo}&${extra}`;
    return `?${extra}`; 
}
Run Code Online (Sandbox Code Playgroud)

我可以使用ifs 轻松地将其移植到 Raku,但我认为使用given/when将是展示该功能的好方法。我想出了以下几点:

sub append(Str :$demo, Str :$file) {
    my $extra = "ctl=1&embed=1";
    given ($demo, $file) {
        when $demo.so,  $file.so  { "/$demo/?file=$file&$extra" } 
        when $demo.not, $file.so  { "/?file=$file&$extra" } 
        when $demo.so,  $file.not { "/$demo?$extra" } 
        default                   { "?$extra" }
    }
}

say append :file("here"), :demo("there"); # /there/?file=here&ctl=1&embed=1
say append :file("here");                 # /?file=here&ctl=1&embed=1
say append :demo("here");                 # /here?ctl=1&embed=1
say append;                               # ?ctl=1&embed=1
Run Code Online (Sandbox Code Playgroud)

然而,它相当重复,我什至不确定它是否是惯用的 Raku,所以我想我可以执行以下操作:

sub append(Str :$demo = '', Str :$file = '') {
    my $extra = "ctl=1&embed=1";
    given ($demo.so, $file.so) {
        when (True,  True)  { "/$demo/?file=$file&$extra" } 
        when (False, True)  { "/?file=$file&$extra" } 
        when (True,  False) { "/$demo?$extra" } 
        default             { "?$extra" }
    }
}
Run Code Online (Sandbox Code Playgroud)

但这并没有按预期工作。因此,是否有可能将值列表绑定到主题变量$_并使用 s 对其进行智能匹配when?我(错误)记得丹尼尔“codesections”索克韦尔做了这样的事情,但我不记得在哪里。

p6s*_*eve 4

我运行了你的代码并得到了这个错误:

Use of uninitialized value of type Str in string context.
Methods .^name, .raku, .gist, or .say can be used to stringify it to something meaningful.
Run Code Online (Sandbox Code Playgroud)

您可以像这样在append()签名中添加默认值来初始化参数值:

sub append(Str :$demo='', Str :$file='') {
Run Code Online (Sandbox Code Playgroud)

哦,不需要do given,简单given就可以了。