cod*_*ons 6 currying rakudo raku
在乐文档说是Code.assuming
返回一个实现与原始行为相同的行为的 Callable,但传递给 .assuming 的值已经绑定到相应的参数。
.assuming在调用内部函数的匿名块(或子)中使用和包装代码之间有什么区别?
例如,在下面的代码中,&surname-public(文档提供的示例.assuming)和&surname-block;之间的区别是什么?
sub longer-names ( $first, $middle, $last, $suffix ) {
say "Name is $first $middle $last $suffix";
}
my &surname-public = &longer-names.assuming( *, *, 'Public', * );
my &surname-block = -> $a,$b,$c { longer-names($a, $b, 'Public', $c) }
surname-public( 'Joe', 'Q.', 'Jr.'); # OUTPUT: «Name is Joe Q. Public Jr.»
surname-block( 'Joe', 'Q.', 'Jr.'); # OUTPUT: «Name is Joe Q. Public Jr.»
Run Code Online (Sandbox Code Playgroud)
我看到这.assuming节省了一些长度,并且在某些情况下可能会更清晰一些。但我强烈怀疑我错过了其他一些差异。
真的没有什么区别。
虽然要实现的代码.assuming()将近 300 行,但重要的一点只有大约 10 行代码。
$f = EVAL sprintf(
'{ my $res = (my proto __PRIMED_ANON (%s) { {*} });
my multi __PRIMED_ANON (|%s(%s)) {
my %%chash := %s.hash;
$self(%s%s |{ %%ahash, %%chash });
};
$res }()',
$primed_sig, $capwrap, $primed_sig, $capwrap,
(flat @clist).join(", "),
(@clist ?? ',' !! '')
);
Run Code Online (Sandbox Code Playgroud)
其余代码.assuming主要是关于从签名中提取信息。
让我们把你的代码插入到那个sprintf.
(不完全相同,但对于我们的目的来说已经足够接近了。)
{
my $res = (
# $primed_sig v----------------------v
my proto __PRIMED_ANON ($first, $middle, $suffix) { {*} }
);
# $capwrap vv
# $primed_sig v----------------------v
my multi __PRIMED_ANON (|__ ($first, $middle, $suffix)) {
# $capwrap vv
my %chash := __.hash;
# v---------------------------v @clist
$self(__[0], __[1], 'Public', __[2], |{ %ahash, %chash });
};
# return the proto
$res
}()
Run Code Online (Sandbox Code Playgroud)
如果我们简化它,并根据您的代码定制它
my &surname-public = {
my $res = (
my proto __PRIMED_ANON ($first, $middle, $suffix) { {*} }
);
my multi __PRIMED_ANON ( $first, $middle, $suffix ) {
longer-names( $first, $middle, 'Public', $suffix )
};
$res
}()
Run Code Online (Sandbox Code Playgroud)
我们可以通过使用一个尖块来进一步简化它。
my &surname-public = -> $first, $middle, $suffix {
longer-names( $first, $middle, 'Public', $suffix )
};
Run Code Online (Sandbox Code Playgroud)
也只需使用单字母参数名称。
my &surname-public = -> $a,$b,$c { longer-names($a, $b, 'Public', $c) }
Run Code Online (Sandbox Code Playgroud)
就像我说的,真的没有区别。
将来,使用.assuming(). 在它被重写以使用 RakuAST 之后。