英文:
How do I smartmatch against a list of values with when inside a given block in Raku?
问题
Here's the translated content you requested:
我发现了这个JS代码片段:
```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}`;
}
我可以轻松地将这个代码移植到Raku,并使用if
语句,但我认为使用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
语句进行智能匹配?我(误)记得Daniel“codesections”Sockwell曾经做过类似的事情,但我记不清在哪里看到的了。
Please note that I've retained the HTML entity references (e.g., `"`) in the translated content as they were in the original text. If you have any specific questions or requests related to this code or translation, feel free to ask.
<details>
<summary>英文:</summary>
I came across this JS code snippet:
```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}`;
}
I can port this easily to Raku using if
s but I thought using given
/when
would be a nice way of showcasing that feature. I came up with the following:
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
However it's quite repetitive and I'm not even sure if it's idiomatic Raku so I figured I could do the following:
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" }
}
}
This doesn't work as expected though. Thus, is it even possible to bind a list of values to the topic variable $_
and smartmatch against it with when
s? I (mis)remember Daniel "codesections" Sockwell doing something to this extent but I cannot remember where.
答案1
得分: 4
我运行了你的代码并得到了这个错误:
在字符串上下文中使用了未初始化的 Str 类型值。
可以使用 .^name、.raku、.gist 或 .say 方法将其转换为有意义的内容。
你可以在 append()
签名中添加默认值来初始化参数值,就像这样:
sub append(Str :$demo='', Str :$file='') {
而且不需要使用 do given
,普通的 given
就可以。
英文:
I ran your code and got this error:
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.
You can just add default values in the append() signature like this to initialize the argument values:
sub append(Str :$demo='', Str :$file='') {
Oh and no need for do given
, just plain given
is fine.
答案2
得分: 2
> 我提出了以下
这是巧合的。您对True
使用smartmatch
在这种情况下,您不需要给出:
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" }
}
}
您可以对Signature
使用smartmatch:
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" }
}
}
但使用multi-dispatch更有趣:
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" }
英文:
> I came up with the following
This works by a coincidence. You use smartmatch against True
You do not need given in this case:
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" }
}
> can I bind a list of values to the topic variable $_ and smartmatch against it with whens?
Yes, you can:
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" }
}
}
You can use smartmatch against Signature
:
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" }
}
}
but it is more fun to use multi-dispatch
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" }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论