将 Subset 中正则表达式的命名捕获放入签名中的变量中

Hol*_*lli 4 raku

考虑

subset MySubset of Str where * ~~ /^ \d $<interesting> = ( \d+ ) $/;
Run Code Online (Sandbox Code Playgroud)

现在我想在我的签名中使用子集作为类型,但是通过解包将捕获的部分放入一个变量中,有点像

sub f( MySubset $( :$interesting ) )
{
    say $interesting;
}

f( "12345678" ); # should say 2345678
Run Code Online (Sandbox Code Playgroud)

这当然行不通。甚至有可能做到这一点吗?

Bra*_*ert 5

子签名解包是将一个值转换为 aCapture并与之匹配。

class Point {
  has ( $.x, $.y );
}

my ( :$x, :$y ) := Point.new( x => 3, y => 4 ).Capture;

say "[$x,$y]"; # [3,4]
Run Code Online (Sandbox Code Playgroud)

由于 aStr没有名为 的公共属性$.interesting,因此不会匹配。

子集只是额外的代码,可以比其他方式更完整地检查值。它不会将值转换为新类型。


如果您使用$<interesting>.

sub f( MySubset )
{
    say $<interesting>;
}
Run Code Online (Sandbox Code Playgroud)

当然,因为块有自己的$/,这也行不通。


虽然将信息从子集传递到签名可能很好,但我不知道这样做。


作为旁注,where已经进行了智能匹配,因此在其中使用它是一个非常糟糕的主意~~

这基本上是您的子集的工作方式:

"12345678" ~~ ( * ~~ /…/ )
Run Code Online (Sandbox Code Playgroud)

在这种特殊情况下,您可以使用 .substr

sub f( MySubset $_ )    {
    .substr(1)
}
Run Code Online (Sandbox Code Playgroud)