在 Raku 的给定块内时,我如何针对值列表进行智能匹配?

问题描述 投票:0回答:2

我遇到了这个 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}`; 
}

我可以使用

if
s 轻松地将它移植到 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

但是它非常重复,我什至不确定它是否是惯用的 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" }
    }
}

但这并不像预期的那样工作。因此,是否有可能将值列表绑定到主题变量

$_
并使用
when
s 对其进行智能匹配?我(错误)记得 Daniel“codesections”Sockwell 在这种程度上做了一些事情,但我不记得在哪里。

pattern-matching raku
2个回答
3
投票

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

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.

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

sub append(Str :$demo='', Str :$file='') {

哦,不需要

do given
,简单的
given
就可以了。


0
投票

我想出了以下内容

这是巧合。你使用 smartmatch 对抗

True

在这种情况下你不需要给出:

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

我可以将值列表绑定到主题变量 $_ 并使用 whens 对其进行智能匹配吗?

是的,你可以:

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

您可以使用smartmatch对抗

Siganture

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

但是使用multidispath

更有趣
constant $extra = 'ctl=1&embed=1';
proto append (Str :$demo,Str :$file) {*}
multi append (:$demo!, :$file!) { "/$demo/?file=$file&$extra" }
multi append (:$file!)          { "/?file=$file&$extra" }
multi append (:$demo!)          { "/$demo?$extra" }
multi append ()                 { "?$extra" }
© www.soinside.com 2019 - 2024. All rights reserved.