小编jja*_*jja的帖子

构建嵌套数据结构时的困难

在尝试为 API 创建 JSON 消息时,我发现自己很难做一些我认为很简单的事情。我需要创建如下消息:

{ "list": [ { "foo": 1, "bar": 2 } ] }
Run Code Online (Sandbox Code Playgroud)

但是,我的第一次尝试没有奏效:

say to-json { foo => [ { a => 1, b => 2 } ] };
# {"foo":[{"a":1},{"b":2}]}
Run Code Online (Sandbox Code Playgroud)

试图简化事情让我更加困惑:

say { foo => [ { a => 1 } ] };
# {foo => [a => 1]}
# Note that this is not JSON, but I expected to see curly braces
Run Code Online (Sandbox Code Playgroud)

然后我尝试使用一些临时变量,并且有效:

my @list = { a => 1 };
say to-json { …
Run Code Online (Sandbox Code Playgroud)

data-structures raku

14
推荐指数
1
解决办法
167
查看次数

我可以在 Nil 上调用任何方法,这感觉不对

我最近花了很多时间调试一个脚本,当我最终发现问题时,是因为代码看起来像这样:

class Foo {
    has $.bar;
    method () {
        # do stuff
        $!.bar;
    }
}
Run Code Online (Sandbox Code Playgroud)

原来,问题是与$!.bar,它应该是要么$!bar$.bar。我明白了。

但这为什么不死

详细看这个,它看起来像这里的问题是,我试图调用(不存在)的方法bar$!,它在这一点上Nil,因为再也没有出现过任何差错。

看起来我实际上可以调用我想要的任何方法,Nil并且它们都默默地返回Nil,包括像Nil.this-is-a-fake-method和这样的东西Nil.reverse-entropy(123)

这是一个功能吗?如果是这样,理由是什么?

raku

14
推荐指数
2
解决办法
243
查看次数

如何在 Raku 中超时承诺?

我知道我可以安排一个Promise在给定的时间内保存

my $promise = Promise.in($seconds);
Run Code Online (Sandbox Code Playgroud)

但我怎样才能安排它被打破?具体来说,我正在考虑一个会“超时”的承诺,这样它就有一定的时间来保留,否则就会失败。

我可以用另一个来做到这一点Promise,就像这样:

my $promise = Promise.new;
...
Promise.in($seconds).then: { $promise.break };
Run Code Online (Sandbox Code Playgroud)

但这感觉有点……浪费。有一个更好的方法吗?

promise raku

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

在 Raku 类定义中,“方法”之前的“has”关键字是什么意思?

最近我意识到我完全错误地编写了这样的 Raku 类之一:

class Foo {
  has method bar {
    return 'some string';
  }
}
Run Code Online (Sandbox Code Playgroud)

我很惊讶地发现这has method不是错误,并且按预期工作。

has在这种情况下做什么?这是故意行为吗?

syntax raku

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

如何在 Raku 中拦截 Proc::Async 的无缓冲输出?

像这样的片段

# Contents of ./run
my $p = Proc::Async.new: @*ARGS;
react {
    whenever Promise.in: 5 { $p.kill               }
    whenever $p.stdout     { say "OUT: { .chomp }" }
    whenever $p.ready      { say "PID: $_"         }
    whenever $p.start      { say "Done"            }
}
Run Code Online (Sandbox Code Playgroud)

./run raku -e 'react whenever Supply.interval: 1 { .say }'
Run Code Online (Sandbox Code Playgroud)

我希望看到类似的东西

PID: 1234
OUT: 0
OUT: 1
OUT: 2
OUT: 3
OUT: 4
Done
Run Code Online (Sandbox Code Playgroud)

但我看到

PID: 1234
OUT: 0
Done
Run Code Online (Sandbox Code Playgroud)

我知道这与缓冲有关:如果我将该命令更改为类似

# The $|++ disables buffering
./run perl …
Run Code Online (Sandbox Code Playgroud)

stdout buffering raku

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

Raku UDP 服务器如何知道将响应发送到哪里?

我可以编写一个 UDP 服务器,它将使用 IO::Socket::Async 从客户端接收消息

my $socket = IO::Socket::Async.bind-udp: 'localhost', 3333;

react whenever $socket.Supply: :bin {
    say "Received some junk: { .gist }";    
}
Run Code Online (Sandbox Code Playgroud)

我可以将东西发送到该服务器:

given IO::Socket::Async.udp {
    await .print-to: 'localhost', 3333, 'Hello';
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试让服务器发回消息响应时,我意识到我没有要发送消息的主机和端口。我怎样才能得到这些信息?

通常,我认为这个问题的答案是使用recvfrom并传递一个指向sockaddr结构的指针,该结构将填充传入连接的地址信息。但如果不使用 NativeCall 似乎就没有办法做到这一点(即使如此,我也不清楚如何做到这一点)。

或者我错过了什么?

sockets udp raku

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

如何在使用 NativeCall 的 Raku 发行版中捆绑 C 源代码?

我正在编写 Raku 绑定到 C 库,但不是要求 Raku 代码的用户自己安装 C 库,我想将 C 代码捆绑为发行版的一部分(它不是那么广泛分布式库)。

我读过有关发行版的%?RESOURCES,这似乎很有用。但是我对如何将其应用于此的具体细节感到模糊。

我是否可以将 C 源代码捆绑在发行版中,并指定某种方式使其作为安装的一部分进行编译(例如,使用zef)?或者我是否需要捆绑库的预编译版本,并获取代码以根据平台选择正确的版本?

或者这根本不可能,我应该向用户提供有关如何单独安装库的说明?

software-distribution nativecall raku

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

如何从散列中构造Perl6中的对象?

在Perl5中,您可以执行以下操作:

#!/usr/bin/env perl
use 5.010;

package Local::Class {
  use Moo;
  has [qw( x y )] => ( is => 'ro');
  sub BUILDARGS { shift; return (@_) ? (@_ > 1) ? { @_ } : shift : {} }
}

use Local::Class;

# Create object directly
my $x = Local::Class->new( x => 1, y => 10 );
say $x->x, ' ', $x->y; # 1 10

# Arguments from a hash
my %hash = ( x => 5, y => 20 …
Run Code Online (Sandbox Code Playgroud)

perl6 object-construction

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

为什么可以通过将尖括号的结果分配给输入记录分隔符来处理文件?

我知道我可以通过将输入记录分隔符($/)设置为未定义的值来吸引文件,例如

open my $fh, '<', $filename or die "Cannot read from $file: $!";
my $contents = do { local $/; <$fh> };
Run Code Online (Sandbox Code Playgroud)

但是最近我遇到了一个非常相似但又不同的成语:

open my $fh, '<', $filename or die "Cannot read from $file: $!";
my $contents = do { local $/ = <$fh> };
Run Code Online (Sandbox Code Playgroud)

(请注意,local $/ = <$fh>而不是local $/; <$fh>)。

这两种的工作,并且对两者的CPAN实例与分配所述变体所述一个无(尽管后者并不奇怪,更为常见)。

但是我的问题是为什么它起作用?作业的变化形式是什么?

PS:我知道我应该使用例如。File :: Slurper可以吞食文件,但是有时候生活很有趣。

perl slurp

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

在Perl6类属性中键入强制

与Perl5中的大多数内容一样,有许多方法可以创建支持其属性的自定义类型强制的类.这是一个简单的,从数组引用到哈希:

#!/usr/bin/env perl

package Local::Class {
  use Moo;
  use Types::Standard qw( HashRef ArrayRef );

  has set => (
    is => 'ro',
    coerce => 1,
    isa => HashRef->plus_coercions(
      ArrayRef, sub { return { map { $_ => 1} @{$_[0]} } },
    ),
  );
}

my $o = Local::Class->new({ set => [qw( a b b c )] });
# $o->set now holds { a => 1, b => 1, c => 1}
Run Code Online (Sandbox Code Playgroud)

我一直试图将这样的东西移植到Perl6,在那里看起来我需要的是一种强制转换Array为a的方法SetHash.到目前为止,我能够做到这一点的唯一方法是:

#!/usr/bin/env perl6

class Local::Class { …
Run Code Online (Sandbox Code Playgroud)

type-conversion perl6 object-construction

5
推荐指数
1
解决办法
113
查看次数

如何在Perl中设置硬的最大递归深度?

虽然在某些情况下我可能希望允许在我的代码中进行深度递归,但我希望能够在某些情况下禁用它(例如在测试时).

我知道在使用调试器时我可以$DB::deep用来指定最大递归深度,而我所使用的功能基本相同,但即使不在调试器中也可以使用.

我看了CPAN,但我找不到任何东西.在PerlMonks上搜索引导我进入一个关于改变深度递归警告行为的线程.我所追求的是能够完全阻止递归(例如,die如果递归过深).

这个功能是否存在?

如果解决方案允许我对其进行本地化,那么奖励点就可以控制最大递归深度的范围.

recursion perl

4
推荐指数
1
解决办法
250
查看次数

在sink上下文中无用的使用LOOP_BLOCK_1符号

用一个代码片段

perl6 -e 'loop { FIRST say "foo"; last }'
Run Code Online (Sandbox Code Playgroud)

我明白了

WARNINGS for -e:
Useless use of LOOP_BLOCK_1 symbol in sink context (line 1)
foo
Run Code Online (Sandbox Code Playgroud)

我知道如何解决警告.我想知道警告的来源是什么.我发现这张门票,但似乎没有得到任何关注.

这个警告是关于什么的?

那怎么回事呢?

$ perl6 --version
This is Rakudo version 2018.06 built on MoarVM version 2018.06
implementing Perl 6.c.
Run Code Online (Sandbox Code Playgroud)

perl6

4
推荐指数
1
解决办法
130
查看次数