我正在尝试使用Perl6语法实现Markdown解析器并且遇到了blockquotes.块引用段落不能嵌套括号来表示,因为它是专门格式化行的列表.但从语义上讲,它是一个嵌套的降价.
基本上,这一切都归结为以下定义:
token mdBlockquote {
<mdBQLine>+ {
my $quoted = [~] $m<mdBQLine>.map: { $_<mdBQLineBody> };
}
}
Run Code Online (Sandbox Code Playgroud)
mdBQLine令牌的实际实现与此无关.唯一需要注意的是,mdBQLineBody密钥包含>已经剥离的实际引用行.毕竟,对于一个块:
> # quote1
> quote2
>
> quote3
quote3.1
Run Code Online (Sandbox Code Playgroud)
该$quoted标将包含:
# quote1
quote2
quote3
quote3.1
Run Code Online (Sandbox Code Playgroud)
现在,重点是解析上述数据并将其注入Match对象$/.这就是我完全陷入困境的地方.最明显的解决方案:
token mdBlockquote {
<mdBQLine>+ {
my $quoted = [~] $m<mdBQLine>.map: { $_<mdBQLineBody> };
$<mdBQParsed> = self.parse( $quoted, actions => self.actions );
}
}
Run Code Online (Sandbox Code Playgroud)
一次失败有两个原因:第一,$/是一个只读对象; 第二,.parse有效地修改它使得无法向原始树中注入任何东西.
是否有任何解决方案,然后分析解析数据,提取和重新解析blockquotes,重复......?
我有一个模块AttrX::Mooish,它实现了Moo/Moose框架的一些属性特性(lazynes,trigger等).我还希望模块对最终用户尽可能透明,这意味着支持私有和公共属性.它的工作原理是将属性的容器替换为a Proxy并将其值存储在外部存储器中.这也意味着Perl6所做的所有类型检查和强制现在都是我的责任.我的目标是尽可能模仿默认行为.即最终用户:
has MyClass @foo is mooish(...);
必须像没有应用特性一样工作.不幸的是,类型操作的主题在语言核心中是如此复杂和不统一,以至于我解决的问题越多,我后来遇到的问题就越多.例如:
my Str @a = <a b c>; my Str @b = [1,2,3]
Type check failed in assignment to @b; expected Str but got Int (1)
正如所料.
my Str @a; say @a.WHAT
(Array[Str])
当然.
my Array[Str] $a = ["a", "b", "c"];
Type check failed in assignment to $a; expected Array[Str] but got Array ($["a", "b", "c"])
好....
my Array[Str] $a = <a b c>;
Type check failed in assignment to …
我试图找到绑定操作如何对属性起作用以及它与之如何不同nqp::bindattr.请考虑以下示例:
class Foo {
has @!foo;
submethod TWEAK {
my $fval = [<a b c>];
use nqp;
nqp::bindattr( nqp::decont(self), $?CLASS, '@!foo',
#@!foo :=
Proxy.new(
FETCH => -> $ { $fval },
STORE => -> $, $v { $fval = $v }
)
);
}
method check {
say @!foo.perl;
}
}
my $inst = Foo.new;
$inst.check;
Run Code Online (Sandbox Code Playgroud)
它打印:
$["a", "b", "c"]
nqp::bindattr从注释中替换绑定运算符可以得到正确的输出:
["a", "b", "c"]
类似地,如果foo使用公共属性和访问器,则由于在访问器内发生去聚合,输出也是正确的.
我在我的AttrX::Mooish模块中使用类似的代码,其中使用:=会使实现过度复杂化.到目前为止,nqp::bindattr在上述问题出现之前,我做得很好.
我试图追查Rakudo的内部寻找:=实施但到目前为止没有任何成功.我会在这里询问有关如何模拟运算符或在源中查找其实现的建议.
我即将选择用于新项目的语言:Perl5或Perl6.到目前为止6胜,只是它缺少了Moo懒惰的属性.我在模块中找到的两个实现缺少关键功能.因此,我尝试编写自己的实现.
我遇到的第一个问题是.package在角色中声明的属性的内容.考虑以下内容:
role HOW1 {
method compose ( Mu $class ) {
note "HOW1.compose";
nextsame;
}
}
role HOW2 {
method compose ( Mu $class ) {
note "HOW2.compose";
nextsame;
}
}
multi trait_mod:<is> (Attribute:D $attr, :$mooish!) {
note "Attribute's package.HOW: ", $attr.package.HOW;
note '$*PACKAGE.HOW: ', $*PACKAGE.HOW;
$attr.package.HOW does HOW1;
$*PACKAGE.HOW does HOW2;
}
class Foo {
has $.bar is mooish;
}
role FooRole {
has $.baz is mooish;
}
Run Code Online (Sandbox Code Playgroud)
脚本的输出如下:
Attribute's package.HOW: Perl6::Metamodel::ClassHOW.new
$*PACKAGE.HOW: …Run Code Online (Sandbox Code Playgroud) 我需要通过Metamodel继承自我的一类实现一些具有一些特殊功能的角色Metamodel::ParametricRoleHOW.应用它的一种方法是使用特征.但我想要一个很好的语法糖,就像我们可以用类做的那样:
special Mine {
...
}
Run Code Online (Sandbox Code Playgroud)
好的,我将以下内容添加到我的模块中:
my package EXPORTHOW {
package DECLARE {
constant special = My::Metamodel::SpecialRoleHOW;
}
}
Run Code Online (Sandbox Code Playgroud)
一切顺利......不,不是:
class Foo does Mine {
...
}
Run Code Online (Sandbox Code Playgroud)
我最终得到:
Could not instantiate role 'Mine':
一个非常简短的检查Actions.nqp显示角色有特殊处理,但仅限于且仅当role关键字用于包声明时.因此,我的结论是有语法糖的唯一途径-是混入我自己的规则到主语法和模拟角色声明.幸运的是,它package_def依赖于$*PKGDECL它,这使得这种模拟成为可能.
我在结论中是对的吗?还是有一种更简单的方法来实现目标?
我正在寻找一些清理我的知识.在具有复杂模块结构的项目中,我希望通过构建结构化命名空间树来保持结构清洁.说,像:
App
Config
Key
Node
Param
Type
MyType
Run Code Online (Sandbox Code Playgroud)
App :: Config下的每个条目都应包含在自己的文件中.总是输入类似的东西App::Config::Key是浪费时间.is export没有参数来声明要导出的名称.所以,我终于找到了以下解决方案:
Config.pm6:
unit module App::Config:ver<0.0.1>;
...
Run Code Online (Sandbox Code Playgroud)
Key.pm6:
unit package App::Config;
class Key is export {
...
}
Run Code Online (Sandbox Code Playgroud)
它按我想要的方式工作:
use App::Config::Key;
say Key.^name; # App::Config::Key
Run Code Online (Sandbox Code Playgroud)
唯一的问题仍然存在:有任何警告吗?知道任何隐藏的副作用?
我正在为我的工作重写从Perl5到Perl6的框架.在某些地方,我需要通过执行sub他们可能提供的公众来从其他模块/类中收集信息; 或者他们可能没有.所以,有必要找出它是否sub存在.当模块直接引用(Foo::<&my-sub>)或字符串中的符号名称(&::("Foo"):: my-sub)时,这不是什么大问题.但为了简单起见,我想允许按原样传递模块名称(假设collector是收集信息的方法):
self.collector( Foo );
Run Code Online (Sandbox Code Playgroud)
凡Foo可能是以下几点:
module Foo {
use Bar;
use Baz;
our sub my-sub { Bar, 'Baz' }
}
Run Code Online (Sandbox Code Playgroud)
这就是我遗漏了Perl6语法中的重要内容,因为以下内容:
method collector ( $mod ) {
my $mod-name = $mod.WHO;
my @mods;
with &::($mod-name)::my-sub {
@mods.push: &$_();
}
}
Run Code Online (Sandbox Code Playgroud)
目前是我可以执行任务的唯一方法.
虽然我没有尝试过类型捕获.我想应该按预期工作.所以,问题更多的是扩展我的语法知识.
基本上,问题更多的是关于语法,但我认为它可能更像是一个关于动态变量的有趣练习.
我有一个带有原型令牌的语法角色(示例被简化以演示这个想法):
proto token foo {*}
token foo:sym<a> {
:my $*delimiter = q<">;
\" ~ \" <value>
}
token foo:sym<b> {
:my $*delimiter = q<'>;
\' ~ \' <value>
}
token value {
.+? <?before $($*delimeter) || $($*custom-delimiter)>
}
Run Code Online (Sandbox Code Playgroud)
当角色被语法消耗时,我希望$*custom-delimiter通过语法来设置.当然,我可以在任何<foo>需要的地方宣布它.但有时可以通过通用默认值进行预初始化.就像是:
{ $*custom-delimiter //= $default-delimiter }
Run Code Online (Sandbox Code Playgroud)
在value令牌中会起作用.但仍需要外部预先申报.
我希望:
our $*custom-delimiter is export = $default-delimiter;
Run Code Online (Sandbox Code Playgroud)
在声明角色的模块范围内可以工作.但显然它没有.所以,问题是:这有什么优雅的解决方案吗?
其实,我也希望该解决方案将允许移动的声明$*delimiter中foo的标记定义之外了.
作为旁注:我的第一个想法是关于向令牌添加参数.但是每个变体的签名完全相同也很糟糕:
token foo:sym<a> ( $*custom-delimiter = $default-delimiter ) {
}
token foo:sym<b> ( $*custom-delimiter = …Run Code Online (Sandbox Code Playgroud) 我找不到正确访问已安装发行版资源的方法.例如,动态加载模块时:
require ::($module);
获取它的一种方法%?RESOURCES是让模块有一个可以返回此哈希的sub:
sub resources { %?RESOURCES }
但这增加了样板代码.
另一种方法是深度扫描$*REPO和获取模块的分布元.
有没有更好的选择来完成这项任务?
主题说明了一切:我可以定义由CONTROL块处理的自己的控制异常吗?应用X :: Control角色是没用的:
class CX::Whatever does X::Control {
method message { "<whatever control exception>" }
}
do {
CX::Whatever.new.throw;
CONTROL {
say "CONTROL!!!";
default {
say "CONTROL: ", $_.WHAT;
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过查看核心资源我可以猜测只有一组预定义的异常才被认为是合适的CONTROL,但不确定我没有错过任何东西.
的文档DBIish指出:
自 2021 年初以来,我成功实施了 Raku 解决方案,使用多达八 (8) 个线程,所有线程均连接到 Oracle,同时执行读取和写入。与 Perl-5 一样,首要要求是确保每个线程创建自己的与 Oracle 的连接句柄。
遵循此规则,我实现了一些基本的池化,其中线程请求连接句柄并在可用时获取它。池中充满连接句柄,直至达到某个预设限制。
还有最常用的准备好的语句句柄的每个连接缓存。
池大小为 1 时效果很好。即,基本上没有多线程。但是,一旦大小设置为 2,我就会terminated by signal SIGKILL (Forced quit)在对数据库进行 20-30 次写入后收到消息。
让我感到困惑的是,接收SIGSEGV或类似的事情会更令人期待。但SIGKILL?好像有什么东西从外部杀死了我的进程?
UPD这一切都是在 Linux 上进行的。Linux Mint,为了清楚起见。
我正在继续探索Perl6深层次的细微实现细节.这次我将自己的方法安装到角色中时遇到问题.当我们开始进入代码之旅时,请系好安全带.
这个想法是一个属性特征,它将方法安装在它所组成的类型对象上.这个问题最初是在私有方法上发现的,我希望将其安装在声明属性的角色中.此时我发现在某些条件下生成的方法引用了来自其闭包的标量无法调用!很可能是由于关闭在运行时丢失.但最令人困惑的一点是,它只发生在角色上,只有当一个角色正在消耗另一个角色时!
所以,这是特质来源:
unit module trait-foo;
role FooClassHOW {...}
role FooAttr {
has $.base-name = self.name.substr(2);
method compose (Mu \type) {
callsame;
if (type.HOW ~~ Metamodel::ClassHOW) && (type.HOW !~~ FooClassHOW) {
type.HOW does FooClassHOW;
}
}
method install-method ( Mu \type ) {
my $attr = self;
type.^add_private_method(
"attr-{$attr.base-name}",
method { "by attr {$attr.name}" }
);
type.^add_method(
"pubattr-{$attr.base-name}",
method { "by attr {$attr.name} - public" }
);
type.^add_private_method(
"check-{$attr.base-name}",
method { "not using closure" }
);
}
}
role FooClassHOW …Run Code Online (Sandbox Code Playgroud) 我已经定义了自己的元模型类来创建一种特殊的类.现在,我希望这些类能够自动注册一个特殊的经理.基本上,这就像这样(只有compose在每次加载类'模块时才会调用):
use MyManager;
class MyHOW is Metamodel::ClassHOW {
method compose ( Mu \type ) {
self.add_parent( type, MyParentClass );
callsame;
registerMyClass( type );
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有类似的东西:
use v6;
use MyClass;
myclass Foo { ... }
Run Code Online (Sandbox Code Playgroud)
在一个模块中.然后有一个管理器对象,它扫描require名称与特定模式匹配的存储库/文件系统和模块.之后,它需要知道myclass每个模块中定义了什么.它可以扫描加载模块的符号表.但是如果加载的文件包含多个模块或根本没有模块,这将无法工作 - 如上例所示.
到目前为止,看起来INIT移相器会提供解决方案,但我很难找到如何从composer方法中获取类的主体块.