小编Hol*_*lli的帖子

并发,一次响应多个供应

请考虑以下代码。为什么输出的是“ BABABA”而不是“ AAABAA” /“ AABAAAB”?这两个供应源不应该并行运行,并且当其中任何一个事件发生时立即火起来吗?

my $i = 0; 
my $supply1 = supply { loop { await Promise.in(3); done if $i++> 5; emit("B"); } };
my $supply2 = supply { loop { await Promise.in(1); done if $i++> 5; emit("A"); } };

react 
{ 
    #whenever Supply.merge($supply1, $supply2) -> $x { $x.print }
    whenever $supply1 -> $x { $x.print };
    whenever $supply2 -> $x { $x.print };
}
Run Code Online (Sandbox Code Playgroud)

rakudo perl6 raku

9
推荐指数
1
解决办法
208
查看次数

在给定位置拆分字符串

我如何在位置列表中很好地/惯用地拆分字符串?

我拥有的:

.say for split-at( "0019ABX26002", (3, 4, 8) ); 

sub split-at( $s, @positions )
{
  my $done = 0;

  gather 
  {
    for @positions -> $p
    {
      take $s.substr($done, $p - $done );
      $done = $p;
    }
    take $s.substr( $done, * );
  }
}
Run Code Online (Sandbox Code Playgroud)

这是合理的。不过,我对此缺乏语言支持感到困惑。如果“split on”是一回事,为什么“split at”也不是?我认为这应该是一个核心操作。我应该可以写

.say for "0019ABX26002".split( :at(3, 4, 8) );
Run Code Online (Sandbox Code Playgroud)

或者也许我忽略了什么?

编辑:到目前为止我们所拥有的一些基准

O------------O---------O------------O--------O-------O-------O
|            | Rate    | array-push | holli  | raiph | simon |
O============O=========O============O========O=======O=======O
| array-push | 15907/s | --         | -59%   | -100% …
Run Code Online (Sandbox Code Playgroud)

raku

9
推荐指数
2
解决办法
167
查看次数

解构对列表

考虑

.say for (1,2,2).rotor(2=>-1).map( -> ($a, $b) { $a - $b })
Run Code Online (Sandbox Code Playgroud)

它按预期工作。然而,

.say for (1,2,2).pairs.rotor(2=>-1).map( -> ($a, $b) { $a.value - $b.value })
Run Code Online (Sandbox Code Playgroud)

投掷

Too few positionals passed to '<anon>'; expected 2 arguments but got 0 in sub-signature
Run Code Online (Sandbox Code Playgroud)

这是一个错误还是我错过了什么?

这是基于实施 Perl 6.d 的 MoarVM 2019.03 版构建的 Rakudo Star 2019.03.1 版。

rakudo raku

9
推荐指数
1
解决办法
200
查看次数

Seq 已经在使用/消耗(嵌套的 gather / take )

sub f()
{
    gather
    {
        take gather { take 3; take 4; take 5; }
        take gather { take 1; take 2; take 3; }
    }
}

say f.sort
Run Code Online (Sandbox Code Playgroud)

The iterator of this Seq is already in use/consumed by another Seq
(you might solve this by adding .cache on usages of the Seq, or
by assigning the Seq into an array)
  in block <unit> at so.raku line 1
Run Code Online (Sandbox Code Playgroud)

然而

sub f()
{
    gather
    {
        take cache gather { take …
Run Code Online (Sandbox Code Playgroud)

raku

9
推荐指数
2
解决办法
114
查看次数

空序列的最小值是无限的,为什么?

我在本周的 PerlWChallenge 上工作。

给定一个整数数组@A。编写一个脚本来创建一个数组,该数组表示每个对应索引左侧的较小元素。如果没有找到,则使用 0。

这是我的方法:

my @A = (7, 8, 3, 12, 10);
my $L = @A.elems - 1;

say gather for 1 .. $L -> $i { take @A[ 0..$i-1 ].grep( * < @A[$i] ).min };
Run Code Online (Sandbox Code Playgroud)

哪种工作和输出:

(7 Inf 3 3)
Run Code Online (Sandbox Code Playgroud)

Infinity 显然来自空的 grep。检查:

> raku -e "().min.say"
Inf
Run Code Online (Sandbox Code Playgroud)

但为什么是空 Seq Infinity 的最小值?如果有的话它应该是-Infinity。还是零?

无论如何,测试空序列可能是个好主意。

我最终使用

take .min with @A[ 0..$i-1 ].grep( * < @A[$i] ) or 0
Run Code Online (Sandbox Code Playgroud)

或者

take ( @A[ 0..$i-1 ].grep( * < @A[$i] ) or …
Run Code Online (Sandbox Code Playgroud)

raku

8
推荐指数
2
解决办法
293
查看次数

意外的非懒惰

我为本周的挑战编写了这段代码,以生成丑陋的数字。

sub factors( $n ) {
  if $n > 1 {
     $_, |factors $n div $_
      given ( grep $n %% *, 2..* ).first } }

.say for ( 1, |grep *.&factors.all ? ( 2, 3, 5 ), 2..* )[^150];
Run Code Online (Sandbox Code Playgroud)

这是有效的,从某种意义上说,它产生了正确的输出,但它的行为并不懒惰:输出不会立即开始,而是在开始后 30 秒开始。

但是,当我删除索引并遍历裸序列时

.say for 1, |grep *.&factors.all ? ( 2, 3, 5 ), 2..*;
Run Code Online (Sandbox Code Playgroud)

我按预期立即得到输出。

这是一个错误,是吗?

lazy-evaluation rakudo raku

8
推荐指数
1
解决办法
99
查看次数

具有内存的标量,或如何正确“绑定”

这是我尝试解决每周挑战#2的尝试。

挑战非常模糊,因此我决定尝试使用内存实现标量值。我对容器的工作方式的理解可能是有缺陷的,但我真正不了解的是,为什么say self.VAR.WHAT是a Proxy而不是a HistoryProxy,即使我明确地说了。

class HistoryProxy is Proxy
{
    has @!history;
    method HISTORY() { @!history };
    method SAVE( $value ) { @!history.push($value) }
}

sub historic(::T $type, $value) {
    my T $c-value = $value;
    return-rw HistoryProxy.new(
        FETCH => method () { $c-value },
        STORE => method (T $new-value) {
            say self.VAR.WHAT;         # Why is this "Proxy" and not "HistoryProxy"?
            self.VAR.SAVE( $c-value ); # Why does this not work?
            $c-value = $new-value;
        }
    ); …
Run Code Online (Sandbox Code Playgroud)

perl6 raku

7
推荐指数
1
解决办法
182
查看次数

CATCH失败失败

我可能忽略了一些简单的事情,但是我不希望下面的代码失败。它表现得好像是我写的,die而不是fail在catch块中的。

无法正确处理故障,代码消失。

sub foo() 
{
  try {
    say 1 / 0;
    CATCH { default { fail "FAIL" } }
  } 

  return True;
}

with foo() { 
    say "done";
}
else
{
  say "handled {.exception.message}"
}
Run Code Online (Sandbox Code Playgroud)

输出:

FAIL
  in block  at d:\tmp\x.pl line 5
  in any  at d:\tmp\x.pl line 5
  in sub foo at d:\tmp\x.pl line 4
  in block <unit> at d:\tmp\x.pl line 11
Run Code Online (Sandbox Code Playgroud)

error-handling perl6 raku

7
推荐指数
1
解决办法
94
查看次数

结合状态和令牌抛出。为什么?

这有效

sub test-string( $string )
{
    my token opening-brace { \( };
    my token closing-brace { \) };
    my token balanced-braces { 
        ( <opening-brace>+ ) <closing-brace> ** { $0.chars } 
    };

    so $string ~~ /^ <balanced-braces> $/;
}
Run Code Online (Sandbox Code Playgroud)

这个

sub test-string( $string )
{
    state token opening-brace { \( };
    state token closing-brace { \) };
    state token balanced-braces { 
        ( <opening-brace>+ ) <closing-brace> ** { $0.chars } 
    };

    so $string ~~ /^ <balanced-braces> $/;
}    
Run Code Online (Sandbox Code Playgroud)

死于

No such method …
Run Code Online (Sandbox Code Playgroud)

regex raku

7
推荐指数
1
解决办法
115
查看次数

NativeCall在Kernel32.dll中找不到函数

我正在尝试将此代码移植到Perl6。虽然我可以打电话GetStdHandleGetConsoleMode而且SetConsoleMode,我的脚本休息,当我试图调用ReadConsoleInput

Cannot locate symbol 'ReadConsoleInput' in native library 'Kernel32.dll'
  in method setup at C:\rakudo\share\perl6\sources\947BDAB9F96E0E5FCCB383124F923A6BF6F8D76B (NativeCall) line 287
  in method CALL-ME at C:\rakudo\share\perl6\sources\947BDAB9F96E0E5FCCB383124F923A6BF6F8D76B (NativeCall) line 576
  in block <unit> at test.p6 line 149
Run Code Online (Sandbox Code Playgroud)

现在,该函数肯定在那里。但是它有一个复杂的签名,我不确定我的脚本是否正确。那可能是原因吗?NativeCall是否查看签名?

这就是我在代码中定义子项的方式(注释摘自MS文档)

#BOOL WINAPI ReadConsoleInput( _In_ HANDLE hConsoleInput, _Out_ PINPUT_RECORD lpBuffer, _In_ DWORD nLength, _Out_ LPDWORD lpNumberOfEventsRead );
sub ReadConsoleInput(Pointer[void], INPUT_RECORD is rw, uint32, uint32 is rw) is native('Kernel32') returns Bool { * };
Run Code Online (Sandbox Code Playgroud)

如果需要,我可以发布其余的代码,但这是很多样板,因为我必须定义所有结构和内容,这些结构和内容通常来自头文件。

windows winapi perl6 nativecall raku

6
推荐指数
1
解决办法
111
查看次数