我可以将容器绑定到新名称:
my %h;
my $p := %h{ "a" }{ "b" }{ "c" };
$p = 1;
say %h;
Run Code Online (Sandbox Code Playgroud)
预期输出:
{a => {b => {c => 1}}}
Run Code Online (Sandbox Code Playgroud)
但是如果我需要从子程序返回这样的指针呢?
my %h;
sub get-pointer {
my $p := %h{ "a" }{ "b" }{ "c" };
return $p;
};
my $q := get-pointer();
$q = 1;
say %h;
Run Code Online (Sandbox Code Playgroud)
给出:
Cannot assign to a readonly variable or a value
Run Code Online (Sandbox Code Playgroud)
那件事让我感到困惑 -$p.WHERE并$q.WHERE给出相同的地址,那么为什么它突然变成只读的?
class A { has $.name; };
class B is A { submethod BUILD { $!name = 'foo' } };
Run Code Online (Sandbox Code Playgroud)
这段代码看起来很自然,但会抛出错误。
Attribute $!name not declared in class B
Run Code Online (Sandbox Code Playgroud)
是的,它没有在 class 中声明B,但我们在部分构造的对象中B::BUILD,并且文档说bless creates the new object, and then walks all subclasses in reverse method resolution order。所以在这个阶段,类的$!name属性应该是已知的B,对吧?
有没有办法在对象构造过程中设置父类属性而不使用new方法?我知道这new可以解决问题,但是BUILD有很多语法糖和BUILD/TWEAK感觉比解析 中的低级blessing更 DWIMy 和直接new。
在Perl 5中,可以轻松模拟在特定时间戳运行的脚本:
BEGIN {
*CORE::GLOBAL::time = sub () { $::time_mock // CORE::time };
}
use Test;
$::time_mock = 1545667200;
ok is-xmas, 'yay!';
$::time_mock = undef; # back to current time
Run Code Online (Sandbox Code Playgroud)
这是全局工作 - 每个包,每个方法,使用time()的所有内容都将看到1545667200时间戳.这对于测试时间敏感逻辑非常方便.
有没有办法在Perl 6中重现这种行为?
我可以通过直接使用令牌名称轻松使用令牌签名:
my token t ( $x ) { $x };
'axb' ~~ / 'a' <t: 'x'> 'b' /; # match
'axb' ~~ / 'a' <t( 'x' )> 'b' /; # match
Run Code Online (Sandbox Code Playgroud)
但是,当令牌存储在变量中时,我还没有找到一种方法来做到这一点:
my $t = token ( $x ) { $x };
'axb' ~~ / 'a' <$t: 'x'> 'b' /;
'axb' ~~ / 'a' <$t( 'x' )> 'b' /;
Run Code Online (Sandbox Code Playgroud)
两者都给出:
===SORRY!=== Error while compiling ...
Unable to parse expression in metachar:sym<assert>; couldn't find final '>'
Run Code Online (Sandbox Code Playgroud)
这样做的神奇语法是什么?
顺便说一句:我什至浏览过 Raku 测试套件,它在roast/S05-grammar/signatures.t …
例如:
$supply.tap: -> $message {
return unless server-is-alive( ); # forbidden!
send-to-server( $message );
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以".tap:sub($ message){return除非...;#works!}".但我想知道是否有任何与块相关的控制流只能中断它.
我想检查数组的所有元素是否都给定了类型。
$ raku -e 'my @t = 1,2,3; say all(@t) ~~ Int'
True
$ raku -e 'my @t = 1,2,3,"a"; say all(@t) ~~ Int'
False
Run Code Online (Sandbox Code Playgroud)
到目前为止按预期工作。现在我想允许两种类型:
$ raku -e 'my @t = 1,2,3,"a"; say all(@t) ~~ Int|Str'
False
Run Code Online (Sandbox Code Playgroud)
为什么会这样?如果1 ~~ Int|Str是True单个元素,为什么all()元素连接失败?
顺便说一句:这个问题是关于理解Junction ~~ Junction行为(这也有点没有记录),而不是关于从示例中执行检查的替代方法(我知道这是可能的)。
我正在寻找解释为什么这两个数据结构不相等:
$ perl6 -e 'use Test; is-deeply [ { a => "b" } ], [ { a => "b" }, ];'
not ok 1 -
# Failed test at -e line 1
# expected: $[{:a("b")},]
# got: $[:a("b")]
Run Code Online (Sandbox Code Playgroud)
哈希和数组中的尾随逗号就像在P5中一样没有意义:
$ perl6 -e '[ 1 ].elems.say; [ 1, ].elems.say'
1
1
Run Code Online (Sandbox Code Playgroud)
但是如果没有它,Hash会以某种方式丢失并且变得扁平化为对数组:
$ perl6 -e '[ { a => "b", c => "d" } ].elems.say;'
2
Run Code Online (Sandbox Code Playgroud)
我怀疑一些Great List Refactor法律适用于此,但我想得到更详细的解释,以了解这种扁平化背后的逻辑.
我正在研究homoglyphs 模块,我必须构建可以找到对应于 ASCII 等效项的同形文字的正则表达式。
因此,例如我有没有同形文字替代品的字符:
my $f = 'f';
Run Code Online (Sandbox Code Playgroud)
和可以混淆的字符:
my @o = 'o', '?', '?'; # ASCII o, Cyrillic o, Greek omicron
Run Code Online (Sandbox Code Playgroud)
我可以轻松构建正则表达式来检测同形文字短语“foo”:
say 'Suspicious!' if $text ~~ / $f @o @o /;
Run Code Online (Sandbox Code Playgroud)
但是,如果我不知道在编译时要检测的值,我应该如何编写这样的正则表达式?假设我想检测在邮件中包含同形文字“现金”字样的网络钓鱼。我可以使用所有替代方法构建序列:
my @lookup = ['c', '?', '?', '?'], ['a', '?', '?'], 's', 'h'; # arbitrary runtime length
Run Code Online (Sandbox Code Playgroud)
现在显然以下解决方案不能将数组元素“解包”到正则表达式中:
/ @lookup / # doing LTM, not searching elements in sequence
Run Code Online (Sandbox Code Playgroud)
我可以通过手动引用每个元素并组合替代项的文本表示来解决此问题,以获取可以作为正则表达式进行评估的字符串。并使用字符串插值从中构建令牌:
my $regexp-ish = textualize( @lookup ); # string "[ 'c' | '?' | '?' …Run Code Online (Sandbox Code Playgroud) 在 Perl 中,我可以:
cat file.txt | perl -nE 'say $.'
Run Code Online (Sandbox Code Playgroud)
我找到的最接近的 Raku 解决方案(不使用状态计数器变量)以字节为单位返回位置:
cat file.txt | raku -ne 'say $*IN.tell'
Run Code Online (Sandbox Code Playgroud) 我需要构建以下流程:
但是我不知道如何正确地将gather-take注入map:
sub MAIN ( *@file-names ) {
@file-names.map( { slip parse-file( $_ ) } ).map( { process-line( $_ ) } );
}
sub parse-file ( $file-name ) {
return gather for $file-name.IO.lines -> $line {
take $line if $line ~~ /a/; # dummy example logic
}
}
sub process-line ( $line ) {
say $line; # dummy example logic
}
Run Code Online (Sandbox Code Playgroud)
这段代码可以工作,但是会疯狂地泄漏内存。我认为slip让人gather-take渴望?或者slip不将Seq …
以下代码按预期崩溃,因为$x不保存数组引用:
$ perl -E 'use strict; use warnings; my $x; say @{$x}; say "OK";'
Can't use an undefined value as an ARRAY reference at -e line 1.
Run Code Online (Sandbox Code Playgroud)
但是,此代码可以在没有任何警告的情况下工作:
perl -E 'use strict; use warnings; my $x; say for @{$x}; say "OK";'
OK
Run Code Online (Sandbox Code Playgroud)
为什么?我在 perldoc 中没有找到任何关于这种行为的文档。看起来for上下文在这里暗示了一些 DWIM-ness 逻辑(具有危险的后果)。